Skip to content

Commit

Permalink
Add support for 5sim service
Browse files Browse the repository at this point in the history
  • Loading branch information
david96182 committed Apr 26, 2024
1 parent 0b9880d commit 2ef6749
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 9 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ The `browser` parameter specifies the browser to be used for automation. The def

The `captcha_keys` parameter is a dictionary that contains the **API keys for supported captcha solving services**, based on `config.toml`. The default value is an empty dictionary. You can provide API keys for specific captcha solving services if required. Currently, **"capsolver"** is supported.

The `sms_keys` parameter is a dictionary that contains the **API key/s for the SMS service/s**, based on `config.toml`. The default value is an empty dictionary. You can provide an API key or keys for the SMS services if required. Currently, **"getsmscode"** and **"smspool"** are supported.
The `sms_keys` parameter is a dictionary that contains the **API key/s for the SMS service/s**, based on `config.toml`. The default value is an empty dictionary. You can provide an API key or keys for the SMS services if required. Currently, **"getsmscode"**, **"smspool"** and **"5sim"** are supported.

The `proxy` parameter specifies the proxy server to be used for the creation of the email accounts. It should be a string in the format "http://ip:port" where "ip" is the IP address of the proxy server and "port" is the port number.

Expand Down Expand Up @@ -258,7 +258,7 @@ Ninjemail currently supports account creation for the following email providers:

## Supported SMS Services

Ninjemail currently supports two SMS services providers for phone verification during account creation:
Ninjemail currently supports three SMS services providers for phone verification during account creation:

**getsmscode.com**

Expand Down Expand Up @@ -298,6 +298,24 @@ To use smspool with Ninjemail, you'll need to acquire the following information:

Replace `token` with your smspool API key.

**[5sim](https://5sim.net/)**

**Required Data:**

To use 5sim with Ninjemail, you'll need to acquire the following information:

- **Token:** Your API token from 5sim.

**Using 5sim with Ninjemail:**

1. Include the `sms_keys` argument when initializing the Ninjemail object:

```python
ninja = Ninjemail(sms_keys={"5sim": {"token": "YOUR_TOKEN"}})
```

Replace `token` with your 5sim API key.

## Contribution

Contributions are welcome! If you have ideas for new features, encounter issues, or want to improve Ninjemail, feel free to contribute by opening issues and pull requests.
Expand Down
2 changes: 1 addition & 1 deletion ninjemail/config.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# config.toml
CAPTCHA_SERVICES_SUPPORTED = ["capsolver"]
DEFAULT_CAPTCHA_SERVICE = "capsolver"
SMS_SERVICES_SUPPORTED = ["getsmscode", "smspool"]
SMS_SERVICES_SUPPORTED = ["getsmscode", "smspool", "5sim"]
DEFAULT_SMS_SERVICE = "smspool"
SUPPORTED_BROWSERS = ['firefox', 'chrome', 'undetected-chrome']

Expand Down
10 changes: 7 additions & 3 deletions ninjemail/email_providers/gmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.remote.webelement import WebElement
from sms_services import getsmscode, smspool
from sms_services import getsmscode, smspool, fivesim

URL = 'https://accounts.google.com/signup'
WAIT = 5
Expand Down Expand Up @@ -64,6 +64,10 @@ def create_account(driver,
data = sms_key['data']
data.update({'service': 395})
sms_provider = smspool.SMSPool(**data)
elif SMS_SERVICE == '5sim':
data = sms_key['data']
data.update({'service': 'google'})
sms_provider = fivesim.FiveSim(**data)

logging.info('Creating Gmail account')

Expand Down Expand Up @@ -129,7 +133,7 @@ def create_account(driver,
try:
if SMS_SERVICE == 'getsmscode':
phone = sms_provider.get_phone(send_prefix=True)
elif SMS_SERVICE == 'smspool':
elif SMS_SERVICE == 'smspool' or SMS_SERVICE == '5sim':
phone, order_id = sms_provider.get_phone(send_prefix=True)
time.sleep(5)
WebDriverWait(driver, WAIT).until(EC.element_to_be_clickable((By.ID, "phoneNumberId"))).send_keys('+' + str(phone) + Keys.ENTER)
Expand All @@ -141,7 +145,7 @@ def create_account(driver,
try:
if SMS_SERVICE == 'getsmscode':
code = sms_provider.get_code(phone)
elif SMS_SERVICE == 'smspool':
elif SMS_SERVICE == 'smspool' or SMS_SERVICE == '5sim':
code = sms_provider.get_code(order_id)
WebDriverWait(driver, WAIT).until(EC.element_to_be_clickable((By.ID, "code"))).send_keys(str(code) + Keys.ENTER)
except Exception as e:
Expand Down
10 changes: 7 additions & 3 deletions ninjemail/email_providers/yahoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from sms_services import getsmscode, smspool
from sms_services import getsmscode, smspool, fivesim
import undetected_chromedriver as uc

URL = 'https://login.yahoo.com/account/create'
Expand Down Expand Up @@ -55,6 +55,10 @@ def create_account(captcha_key,
data = sms_key['data']
data.update({'service': 1034})
sms_provider = smspool.SMSPool(**data)
elif SMS_SERVICE == '5sim':
data = sms_key['data']
data.update({'service': 'yahoo'})
sms_provider = fivesim.FiveSim(**data)

if type(driver) is webdriver.Firefox:
driver.install_addon(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'captcha_solvers/capsolver_captcha_solver-1.10.4.xpi'))
Expand Down Expand Up @@ -137,7 +141,7 @@ def create_account(captcha_key,
# get and insert phone
if SMS_SERVICE == 'getsmscode':
phone = sms_provider.get_phone(send_prefix=False)
elif SMS_SERVICE == 'smspool':
elif SMS_SERVICE == 'smspool' or SMS_SERVICE == '5sim':
phone, order_id = sms_provider.get_phone(send_prefix=False)
time.sleep(2)
WebDriverWait(driver, WAIT).until(EC.element_to_be_clickable((By.ID, "usernamereg-phone"))).send_keys(str(phone) + Keys.ENTER)
Expand Down Expand Up @@ -187,7 +191,7 @@ def create_account(captcha_key,
try:
if SMS_SERVICE == 'getsmscode':
code = sms_provider.get_code(phone)
elif SMS_SERVICE == 'smspool':
elif SMS_SERVICE == 'smspool' or SMS_SERVICE == '5sim':
code = sms_provider.get_code(order_id)
WebDriverWait(driver, WAIT).until(EC.element_to_be_clickable((By.ID, "verification-code-field"))).send_keys(str(code) + Keys.ENTER)
except:
Expand Down
144 changes: 144 additions & 0 deletions ninjemail/sms_services/fivesim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import logging
import re
import time

import requests

PREFIXES = {
"usa":"1",
}

class APIError(Exception):
pass

class FiveSim:
"""
This class provides functionalities to interact with the 5Sim API to obtain phone numbers and SMS verification codes.
Attributes:
token (str): Your 5Sim api key.
service (str): 5Sim service name.
country (str, optional): The country name for the phone number. Defaults to 'usa'.
Methods:
request(kwargs): Sends a GET request to the 5Sim API with the provided arguments.
get_phone(send_prefix=False): Purchases a phone number from the 5Sim API.
- send_prefix (bool, optional): Specifies whether to return the phone number with or without the prefix. Defaults to False.
get_code(phone): Retrieves the SMS verification code sent to the provided phone number.
Exceptions:
APIError: Raised when an error occurs while interacting with the 5Sim API.
"""

_last_phone = None
code_patt = re.compile(r"([0-9]{5,6})")

def __init__(
self,
service,
token,
country='usa',
):
self.token = token
self.service = service
self.country = country
self.prefix = PREFIXES.get(self.country) or ''
self.API_URL = "https://5sim.net/v1/user/"

def request(self, cmd):
"""
Sends a GET request to the 5Sim API with the provided arguments.
Args:
kwargs (dict): Additional arguments to be included in the request body.
Returns:
str: The API response text.
Raises:
APIError: If the API returns an error message.
"""
headers = {
'Authorization': 'Bearer ' + self.token,
}

res = requests.get(
self.API_URL + cmd,
headers=headers,
)
try:
res.raise_for_status()
except requests.exceptions.HTTPError as err:
raise APIError(str(err))

if res.text == "no free phones":
raise APIError('5Sim has no free phones')
if res.text == "not enough user balance":
raise APIError("Not enough balance")

return res.json()

def get_phone(self, send_prefix=False):
"""
Purchases a phone number from the 5Sim API.
Args:
send_prefix (bool, optional): Specifies whether to return the phone number with or without the prefix. Defaults to False.
Returns:
str: The retrieved phone number, optionally with the prefix removed and the order id of the purchased phone number.
Raises:
APIError: If an error occurs while retrieving the phone number.
"""
logging.info("Getting a phone number")

cmd = 'buy/activation/' + self.country + '/any/' + self.service
data = self.request(cmd=cmd)

self._last_phone = data
phone_number = data['phone']
phone_number = phone_number.removeprefix('+')
order_id = data['id']

logging.info("Got phone: %s", phone_number)

if not send_prefix:
phone_number = phone_number.removeprefix('1')
return phone_number, order_id

def get_code(self, order_id):
"""
Retrieves the SMS verification code sent to the provided phone number.
Args:
order_id (str): The order_id to retrieve the code for the sms.
Returns:
str: The extracted SMS verification code.
Raises:
APIError: If an error occurs while retrieving the code.
AssertionError: If no code is found in the API response.
"""
logging.info("Getting the verification code")

cmd = '/check/' + str(order_id)
received = False
while not received:
res = self.request(cmd=cmd)
if res['sms']:
received = True
elif res['status'] in ['CANCELED', 'TIMEOUT', 'BANNED']:
raise APIError('Error getting verification code, order status: %s' % res['status'])
else:
logging.info("Retrying...")
time.sleep(10)

sms = res['sms']
code = sms[0]['code']

logging.info("Got code %s", code)
return code


28 changes: 28 additions & 0 deletions ninjemail/tests/test_email_gmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def mock_get_phone_getsmscode(self, *args, **kwargs):
def mock_get_phone_smspool(self, *args, **kwargs):
return 'ordeid', '111111111'

def mock_get_phone_fivesim(self, *args, **kwargs):
return 'ordeid', '111111111'

def mock_get_code(self, *arg, **kwargs):
return '000000'

Expand Down Expand Up @@ -116,6 +119,31 @@ def test_create_account_chrome_and_smspool(monkeypatch):
assert email == f"{username}@gmail.com"
assert password == "testpassword"

def test_create_account_chrome_and_fivesim(monkeypatch):
monkeypatch.setattr('sms_services.fivesim.FiveSim.get_phone', mock_get_phone_fivesim)
monkeypatch.setattr('sms_services.fivesim.FiveSim.get_code', mock_get_code)

driver = create_driver('chrome')
# Test data
sms_key = {
"name": "5sim",
"data": {
"token": "your_api_key",
"service": "google"
}
}
username = "testuser"
password = "testpassword"
first_name = "John"
last_name = "Doe"
month = "1"
day = "1"
year = "2000"

email, password = create_account(driver, sms_key, username, password, first_name, last_name, month, day, year)
assert email == f"{username}@gmail.com"
assert password == "testpassword"

def test_create_account_phone_fail(monkeypatch):
monkeypatch.setattr('sms_services.getsmscode.GetsmsCode.get_phone', mock_get_phone_fail)

Expand Down
30 changes: 30 additions & 0 deletions ninjemail/tests/test_email_yahoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def mock_get_phone_getsmscode(self, *args, **kwargs):
def mock_get_phone_smspool(self, *args, **kwargs):
return 'ordeid', '111111111'

def mock_get_phone_fivesim(self, *args, **kwargs):
return 'ordeid', '111111111'

def mock_get_code(self, *arg, **kwargs):
return '000000'

Expand Down Expand Up @@ -124,6 +127,33 @@ def test_create_account_chrome_and_smspool(monkeypatch):
assert email == f"{username}@yahoo.com"
assert password == "testpassword"

def test_create_account_firefox_and_fivesim(monkeypatch):
monkeypatch.setattr('sms_services.fivesim.FiveSim.get_phone', mock_get_phone_fivesim)
monkeypatch.setattr('sms_services.fivesim.FiveSim.get_code', mock_get_code)

driver = create_driver('firefox')
# Test data
captcha_key= "4564654777"
sms_key = {
"name": "5sim",
"data": {
"service": "yahoo",
"token": "your_api_key",
}
}
username = "testuser"
password = "testpassword"
first_name = "John"
last_name = "Doe"
month = "1"
day = "1"
year = "2000"
myyahoo = False

email, password = create_account(captcha_key, driver, sms_key, username, password, first_name, last_name, month, day, year, myyahoo)
assert email == f"{username}@yahoo.com"
assert password == "testpassword"

def test_create_myyahoo_account(monkeypatch):
monkeypatch.setattr('sms_services.smspool.SMSPool.get_phone', mock_get_phone_smspool)
monkeypatch.setattr('sms_services.smspool.SMSPool.get_code', mock_get_code)
Expand Down
Loading

0 comments on commit 2ef6749

Please sign in to comment.