From 13c4e358b9a83f25e9eebbf153f92fb455790fcb Mon Sep 17 00:00:00 2001 From: Yandrik Date: Sat, 16 Mar 2024 13:38:40 +0100 Subject: [PATCH] feat: stuff --- .idea/misc.xml | 2 +- addy_api.py | 112 ++++++++++++++++++++++++++++++++- main.py | 167 ++++++++++++++++++++++++++++++++++++++++++------- poetry.lock | 29 ++++++++- pyproject.toml | 2 + 5 files changed, 285 insertions(+), 27 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 7a117f1..defdff5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/addy_api.py b/addy_api.py index 1667846..f72ca8a 100644 --- a/addy_api.py +++ b/addy_api.py @@ -1,9 +1,9 @@ import requests -from typing import Union, Dict, Any +from typing import Union, Dict, Any, List -def create_alias(api_token: str, alias_domain: str, alias_description: str) -> Union[Dict[str, Any], str]: +def create_alias(api_token: str, alias_domain: str, alias_description: str, recipient_ids: List[str] | None) -> Union[Dict[str, Any], str]: """ Creates a new alias using the provided API token, domain and description. @@ -28,8 +28,12 @@ def create_alias(api_token: str, alias_domain: str, alias_description: str) -> U api_url = 'https://app.addy.io/api/v1/aliases' payload = { 'domain': alias_domain, - 'description': alias_description + 'description': alias_description, } + + if recipient_ids: + payload['recipient_ids'] = recipient_ids + response = requests.post(api_url, headers=headers, json=payload) if response.status_code == 201: @@ -65,7 +69,109 @@ def delete_alias(api_token: str, alias_id: str) -> str: return f'Failed to delete alias: {response.status_code} - {response.text}' +def create_recipient(api_token: str, recipient_email: str) -> Union[Dict[str, Any], str]: + """ + Creates a new recipient using the provided API token and recipient email. + + grab the ['data']['id'] for setting recipients on aliases, or deleting them + + :param api_token: The API token used for authentication. + :type api_token: str + :param recipient_email: The email of the recipient to be created. + :type recipient_email: str + :return: The API response in case of success, or error string in case of failure. + :rtype: Dict[str, Any] or str + """ + headers = { + 'Authorization': f'Bearer {api_token}', + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + } + api_url = 'https://app.addy.io/api/v1/recipients' + payload = { + 'email': recipient_email + } + response = requests.post(api_url, headers=headers, json=payload) + + if response.status_code == 201: + # Recipient created successfully + return response.json() + else: + return f'Failed to create recipient: {response.status_code} {response.text}' + + +def delete_recipient(api_token: str, recipient_id: str) -> str: + """ + Deletes a specific recipient using the provided API token and recipient ID. + + :param api_token: The API token used for authentication. + :type api_token: str + :param recipient_id: The ID of the recipient to be deleted. + :type recipient_id: str + :return: Success message if the recipient is deleted successfully, or an error message otherwise. + :rtype: str + """ + api_url = f'https://app.addy.io/api/v1/recipients/{recipient_id}' + headers = { + 'Authorization': f'Bearer {api_token}', + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + } + + response = requests.delete(api_url, headers=headers) + + if response.status_code == 204: + return 'Recipient deleted successfully.' + else: + return f'Failed to delete recipient: {response.status_code} - {response.text}' + + +def get_all_recipients(api_token: str, verified: bool = None) -> Union[Dict[str, Any], str]: + """ + Retrieves all recipients, optionally filtering by verification status. + + :param api_token: The API token used for authentication. + :type api_token: str + :param verified: Optional; if specified, filters recipients by their verification status. + :type verified: bool + :return: The API response in case of success, or error string in case of failure. + :rtype: Dict[str, Any] or str + """ + headers = { + 'Authorization': f'Bearer {api_token}', + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + } + api_url = 'https://app.addy.io/api/v1/recipients' + + # Add query parameters if 'verified' is not None + params = {} + if verified is not None: + params['filter[verified]'] = str(verified).lower() + + response = requests.get(api_url, headers=headers, params=params) + + if response.status_code == 200: + # Recipients retrieved successfully + return response.json() + else: + return f'Failed to retrieve recipients: {response.status_code} {response.text}' + + +# Example usage if __name__ == "__main__": + api_token = 'insert_api_key' + recipient_id = '46eebc50-f7f8-46d7-beb9-c37f04c29a84' # Example recipient ID + + response = delete_recipient(api_token, recipient_id) + print(response) + + api_token = 'insert_api_key' + recipient_email = 'me@example.com' + + response = create_recipient(api_token, recipient_email) + print(response) + api_token = 'insert_api_key' alias_domain = 'addy.io' # Generates random alias alias_description = 'Randomly generated alias' diff --git a/main.py b/main.py index d6dcec4..1950200 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,15 @@ +import argparse +import poplib +import re import time from datetime import datetime +from email.header import decode_header +from email.parser import Parser + +from selenium.webdriver.firefox.service import Service as FirefoxService from faker import Faker +from guerrillamail import GuerrillaMailSession from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By @@ -13,10 +21,28 @@ from webdriver_manager.chrome import ChromeDriverManager from urllib.parse import urlparse, urlunparse +from webdriver_manager.firefox import GeckoDriverManager + import addy_api import smspool_api +def firefoxdriver(): + # Set up Firefox options if necessary + # Initialize the WebDriver instance with GeckoDriverManager + driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install())) + + # Use the driver to navigate + return driver + + +def chromedriver(): + CHROMIUM_PATH = '/usr/bin/chromium-browser' + options = webdriver.ChromeOptions() + options.binary_location = CHROMIUM_PATH + # Set up the Chrome WebDriver + driver = webdriver.Chrome(options=options) + return driver def test_url_ignore_params(driver: webdriver, expected_url: str) -> None: """ Assert that the current URL matches the expected URL, ignoring query parameters and anchors. @@ -82,12 +108,8 @@ def get_key(): secrets = load_keys('keys.secret') # print(keys_data) - CHROMIUM_PATH = '/usr/bin/chromium-browser' - - options = webdriver.ChromeOptions() - options.binary_location = CHROMIUM_PATH - # Set up the Chrome WebDriver - driver = webdriver.Chrome(options=options) + # driver = chromedriver() + driver = firefoxdriver() # Open the Google homepage driver.get("https://console.anthropic.com/login") @@ -95,37 +117,81 @@ def get_key(): print('doing signup step') onboarding = False + # input() + time.sleep(1) # Find the search box using its name attribute value email_box = driver.find_element("id", "email") + # get pop3 connection + + # print(server.list()) + + print(get_subject_of_last_email(secrets)) + + # print(response, lines, octets) + + # get all recipients addy.io + + all_recipients = addy_api.get_all_recipients(api_token=secrets['ANONADDY_API_KEY'])['data'] + addy_recipient_id = None + for recipient in all_recipients: + if recipient['email'] == secrets['MAIL_ADDR']: + addy_recipient_id = recipient['id'] + + if not addy_recipient_id: + raise ValueError(f'Recipient with email {secrets["MAIL_ADDR"]} doesn\'t exist, please create it') + # get new alias alias = addy_api.create_alias(api_token=secrets['ANONADDY_API_KEY'], alias_domain='addy.io', - alias_description='temp alias for anthropic') + alias_description='temp alias for anthropic', + recipient_ids=[addy_recipient_id]) print(alias) mail = alias['data']['email'] + # get last subject + last_subject = get_subject_of_last_email(secrets) + print('last subject:', last_subject) + email_box.send_keys(mail) email_box.send_keys(Keys.ENTER) while not onboarding: while True: - try: - login_code = input("Check your inbox for the login code!\nLogin Code > ") - if len(login_code.strip()) != 6: - print("Make sure to enter the six digit number!") - continue - int(login_code) + print('checking inbox') + subject = get_subject_of_last_email(secrets) + print('cur subject:', subject) + if last_subject != subject: + print(subject) + + # find code + pattern = r"\b\d{6}\b" + match = re.search(pattern, subject) + login_code = match.group() + print(f"login code is {login_code}") + # login_code = input('whats the code > ') break - except ValueError as e: - print("An error occurred. Make sure to enter a six digit integer.") + time.sleep(2) + + # try: + # login_code = input("Check your inbox for the login code!\nLogin Code > ") + # if len(login_code.strip()) != 6: + # print("Make sure to enter the six digit number!") + # continue + # int(login_code) + # break + # except ValueError as e: + # print("An error occurred. Make sure to enter a six digit integer.") code_box = driver.find_element("id", "code") code_box.clear() code_box.send_keys(str(login_code)) code_box.send_keys(Keys.RETURN) + # delete email alias + addy_api.delete_alias(api_token=secrets['ANONADDY_API_KEY'], alias_id=alias['data']['id']) + on_onboarding_page = lambda: remove_query_and_anchor(driver.current_url).endswith('onboarding') for i in range(10): @@ -212,19 +278,53 @@ def get_key(): country_dropdown = driver.find_element(By.CLASS_NAME, 'PhoneInputCountrySelect') select = Select(country_dropdown) - select.select_by_value('GB') + + PhoneNumberCountry = "GB" + # PhoneNumberCountry = "LV" # Latvia + # PhoneNumberCountry = "KZ" # Kazachstan + # PhoneNumberCountry = "US" + # PhoneNumberCountry = "ID" # Indonesia + # PhoneNumberCountry = "VN" # Vietnam + # PhoneNumberCountry = "KG" # Kyrgyzstan + # PhoneNumberCountry = "MY" # Malaysia + # PhoneNumberCountry = "IL" # Israel + # PhoneNumberCountry = "TH" # Thailand + # PhoneNumberCountry = "PK" # Pakistan + # PhoneNumberCountry = "KE" # Kenya + # PhoneNumberCountry = "BR" # Brazil + + + # pool = None + pool = 'Mike' + # pool = 'Foxtrot' + + + wait_time = 0 + # wait_time = 180 # recommended for phone numbers that need to be activated first + + # pricing_option = 0 # cheapest numbers + pricing_option = 1 # highest success rate + + service = '817' # other + + + select.select_by_value(PhoneNumberCountry) phone_num_field = driver.find_element('id', 'free_credits_phone_number') # input('enter > ') # get new phone number for verification - sms = smspool_api.post_order_sms(bearer_token=secrets['SMSPOOL_API_KEY'], country='GB', - service='817') # service='1371') # ClaudeAI + sms = smspool_api.post_order_sms(bearer_token=secrets['SMSPOOL_API_KEY'], country=PhoneNumberCountry, + service=service, pricing_option=pricing_option, pool=pool) # print(sms) number = sms['number'] + if wait_time > 0: + print(f'sleeping for {wait_time} seconds to wait for phone num activation') + time.sleep(wait_time) + phone_num_field.send_keys(number) phone_num_field.send_keys(Keys.ENTER) @@ -287,12 +387,37 @@ def get_key(): key_text = driver.find_element("xpath", "//p[starts-with(text(), 'sk-ant-')]").text print('key:', key_text) - addy_api.delete_alias(api_token=secrets['ANONADDY_API_KEY'], alias_id=alias['data']['id']) return key_text, name # delete alias +def get_subject_of_last_email(secrets) -> str: + server = poplib.POP3_SSL(secrets['MAIL_URL']) + server.set_debuglevel(1) # Set to 0 to disable debug output + + server.user(secrets['MAIL_USER']) + server.pass_(secrets['MAIL_PASS']) + num_emails = len(server.list()[1]) + print(num_emails) + response, lines, octets = server.retr(num_emails) + msg_content = b'\r\n'.join(lines).decode('utf-8') + msg = Parser().parsestr(msg_content) + subject = decode_header(msg['Subject'])[0][0] + if isinstance(subject, bytes): + subject = subject.decode('utf-8') + return subject + + if __name__ == '__main__': - key, name = get_key() - append_api_key_to_file('apikeys.txt', name, key) + # Set up argparse + parser = argparse.ArgumentParser(description='Repeat the key getting process N times.') + parser.add_argument('--repetitions', type=int, default=1, + help='Number of times to repeat the key getting process. Default is 1.') + args = parser.parse_args() + + # Repeat the key getting process based on the --repetitions argument + for _ in range(args.repetitions): + key, name = get_key() + append_api_key_to_file('apikeys.txt', name, key) + print(f'Key: {key}, Name: {name}') diff --git a/poetry.lock b/poetry.lock index 56c9847..a88dd65 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,15 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. + +[[package]] +name = "argparse" +version = "1.4.0" +description = "Python command-line parsing library" +optional = false +python-versions = "*" +files = [ + {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"}, + {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"}, +] [[package]] name = "attrs" @@ -393,6 +404,20 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-guerrillamail" +version = "0.2.0" +description = "Client for the Guerrillamail temporary email server" +optional = false +python-versions = "*" +files = [ + {file = "python-guerrillamail-0.2.0.tar.gz", hash = "sha256:f04c48c58ddc55f81c2fe63c43e5f8d806ea77695fc621fe8bdbc11413bf9e31"}, + {file = "python_guerrillamail-0.2.0-py2.py3-none-any.whl", hash = "sha256:993934d09cdba4c0f8a70b00eedf3563acabdec3e24bb82335121a0e022afff5"}, +] + +[package.dependencies] +requests = "*" + [[package]] name = "pytz" version = "2024.1" @@ -667,4 +692,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "c8639fb21fe3799208b80d5b92c2222286012258d1f6d6381d659173ef4d4c51" +content-hash = "43d56979dd2188dbd4219ac3b0a9f71c82928788ca9e0beca63c896718de1bff" diff --git a/pyproject.toml b/pyproject.toml index 2ff8af3..a90d85e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,8 @@ smspool = "^0.0.4" webdriver-manager = "^4.0.1" faker = "^24.2.0" datetime = "^5.4" +python-guerrillamail = "^0.2.0" +argparse = "^1.4.0" [tool.poetry.group.dev.dependencies] pytest = "^8.1.1"