aiosmsactivate.client
1import asyncio 2import json 3import logging 4import re 5import time 6from typing import Any, Literal 7from cachetools import TTLCache, cached 8 9import aiohttp 10 11from .utils import is_json 12from .exceptions import SmsActivateException, raise_smsactivate_error 13from .models import ActivationData, Number, Service, SetActivationStatusResponse, Sms 14from .types import SetActivationStatus, ActivationStatus 15 16cache = TTLCache(maxsize=100, ttl=3600) 17 18__all__ = [ 19 "SmsActivate", 20] 21 22 23allowed_domains = [ 24 'https://api.sms-activate.ae/stubs/handler_api.php', 25 'https://api.sms-activate.ru/stubs/handler_api.php', 26 'https://api.sms-activate.io/stubs/handler_api.php', 27 'https://api.sms-activate.page/stubs/handler_api.php', 28] 29 30class SmsActivate: 31 """ 32 RU 33 Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки 34 35 ВАЖНО 36 библиотека полностью поддерживает все методы с оффициальной документации 37 https://sms-activate.page/api2 на момент 08.07.2025 38 39 на git: https://github.com/AioSmsProviders/aiosmsactivate 40 Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi 41 или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof 42 43 EN 44 Thank you for using my library, you can participate in the development of the library. 45 46 important 47 The library fully supports all methods from the official documentation 48 https://sms-activate.page/api2 as of 07/08/2025 49 50 on git: https://github.com/AioSmsProviders/aiosmsactivate 51 You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi 52 or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof 53 54 SIMPLE USAGE 55 ```python 56 from aiosmsactivate import SmsActivate 57 from aiosmsactivate.types import SetActivationStatus 58 59 import asyncio 60 61 62 sa = SmsActivate('token') 63 64 async def main(): 65 balance = await sa.get_balance() 66 print(balance) # 6.25 67 68 number = await sa.purchase('ya') 69 number.activation_id # 3807035855 70 number.phone_number # '79238944456' 71 number.operator # 'mtt' 72 print(number) 73 # activation_id=3807035855 phone_number='79238944456' activation_cost=0.2 74 # country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27' 75 # operator='mtt' 76 77 code = await number.wait_sms_code(timeout=300) 78 print(code) # 1234 79 80 status = await number.get_activation_status() 81 82 await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number 83 await number.set_activation_status(8) # Отменить номер || Cancel number 84 85 asyncio.run(main()) 86 ``` 87 """ 88 89 def __init__(self, api_key: str, base_url: str | list = allowed_domains): 90 """ 91 RU 92 api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile 93 В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий 94 а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains 95 96 EN 97 api_key to transfer the api key, you can get it here: https://sms-activate.page/profile 98 You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one. 99 or you can specify one or not at all, if not specified, it will be taken from allowed_domains. 100 """ 101 self._api_key = api_key 102 if isinstance(base_url, str): 103 base_url = [base_url] 104 self._base_urls = base_url 105 self._accept_url = None 106 107 async def __send_request(self, action: str, **kwargs): 108 last_exception = None 109 110 for url in self._base_urls: 111 try: 112 url = self._accept_url if self._accept_url else url 113 params = None 114 if 'params' in kwargs.keys(): 115 params = kwargs.pop('params') 116 async with aiohttp.ClientSession() as session: 117 async with session.request( 118 'POST', 119 url, 120 **kwargs, 121 params={ 122 'api_key': self._api_key, 123 'action': action, 124 **(params if params else {}) 125 } 126 ) as response: 127 response.raise_for_status() 128 resp_text = await response.text() 129 raise_smsactivate_error(resp_text) 130 logging.debug(response.real_url) 131 return resp_text 132 except Exception as e: 133 last_exception = e 134 continue 135 self._accept_url = url 136 break 137 138 raise last_exception 139 140 async def get_balance(self, cashback: bool = False) -> float: 141 pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})') 142 response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack') 143 match = pattern.match(response) 144 if not match: 145 raise SmsActivateException('Invalid response sequence') 146 147 return float(match.group(1)) 148 async def get_balance_and_cashback(self): 149 return await self.get_balance(cashback=True) 150 151 async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]: 152 response = await self.__send_request('getTopCountriesByService', params={ 153 'service': service, 154 'freePrice': str(freePrice).lower() 155 }) 156 157 if not is_json(response): 158 return response 159 160 return json.loads(response) 161 162 async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]: 163 response = await self.__send_request('getNumbersStatus', params={ 164 'country': country, 165 'operator': operator 166 }) 167 168 if not is_json(response): 169 return response 170 171 return json.loads(response) 172 173 async def get_operators(self, country: str = None) -> dict[str, Any]: 174 params = {} 175 if country is not None: 176 params["country"] = country 177 response = await self.__send_request('getOperators', params=params) 178 179 if not is_json(response): 180 return response 181 182 return json.loads(response) 183 184 async def get_active_activations(self) -> dict[str, Any]: 185 response = await self.__send_request('getActiveActivations') 186 187 if not is_json(response): 188 return response 189 190 return json.loads(response) 191 192 async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]: 193 response = await self.__send_request('getStatus', params={ 194 'id': id 195 }) 196 197 data = response.split(':') 198 199 match data[0]: 200 case 'STATUS_WAIT_CODE': 201 return ActivationStatus.WAIT, None 202 case 'STATUS_WAIT_RETRY': 203 return ActivationStatus.RETRY, data[1] 204 case 'STATUS_WAIT_RESEND': 205 return ActivationStatus.RESEND, None 206 case 'STATUS_CANCEL': 207 return ActivationStatus.CANCEL, None 208 case 'STATUS_OK': 209 return ActivationStatus.OK, data[1] 210 case _: 211 raise SmsActivateException('Invalid response sequence') 212 213 async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str: 214 if isinstance(activation_id, Number): 215 activation_id = activation_id.activation_id 216 response = await self.__send_request('getStatusV2', params={ 217 'id': activation_id 218 }) 219 220 if not is_json(response): 221 return response 222 223 return ActivationData(**json.loads(response)) 224 225 async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None: 226 """ 227 Ожидание смс кода 228 Wait sms code 229 230 Аргументы: 231 activation_id: activation_id номера или целый объект номера 232 timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 233 per_attempt: время между попыткой получить смс, по умолчанию 5 секунд 234 235 Args: 236 activation_id: activation_id of number or Number object 237 timeout: maximum time to wait sms code 238 per_attempt: time per attempt 239 240 Returns: Sms 241 """ 242 activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id 243 if not self._api_key: 244 raise ValueError('API key is required for this method') 245 246 try: 247 await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY) 248 except: 249 pass 250 251 start_time = time.time() 252 253 while time.time() - start_time < timeout: 254 await asyncio.sleep(per_attempt) 255 status, code = await self.get_activation_status_v1(activation_id) 256 if status == ActivationStatus.OK: 257 try: 258 await self.set_activation_status(activation_id, SetActivationStatus.AGAIN) 259 except: 260 pass 261 return code 262 263 return None 264 265 async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None, 266 phoneException: str | None = None, operator: str | None = None, 267 activationType: int | str | None = None, language: str | None = None, 268 userId: str | int | None = None, 269 ref: str | None = None, country: str | None = None, 270 useCashBack: bool | None = None, 271 orderId: str | int | None = None, 272 _is_v2: bool = True 273 ) -> Number | str: 274 response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={ 275 'service': service, 276 **({'forward': 1 if forward else 0} if forward is not None else {}), 277 **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}), 278 **({'phoneException': phoneException} if phoneException is not None else {}), 279 **({'operator': operator} if operator is not None else {}), 280 **({'activationType': str(activationType)} if activationType is not None else {}), 281 **({'language': str(language)} if language is not None else {}), 282 **({'userId': str(userId)} if userId is not None else {}), 283 **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}), 284 **({'ref': ref} if ref is not None else {}), 285 **({'country ': country} if country is not None else {}), 286 **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}), 287 }) 288 289 if not is_json(response): 290 return response 291 292 return Number.from_response(self, json.loads(response)) 293 294 async def get_number(self, *args, **kwargs): 295 kwargs["_is_v2"] = False 296 return await self.purchase(*args, **kwargs) 297 298 async def get_multi_service_number(self, 299 multiService: str, multiForward: str | None = None, 300 operator: str | None = None, 301 ref: str | None = None, country: str | None = None, 302 ) -> dict: 303 """ 304 Get multiservice number. 305 306 :param multiService: service1,service2,service3 (Services separated by commas) 307 :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count) 308 :return: dict object of response 309 """ 310 response = await self.__send_request('getMultiServiceNumber', params={ 311 'multiService': multiService, 312 **({'multiForward': multiForward} if multiForward is not None else {}), 313 **({'operator': operator} if operator is not None else {}), 314 **({'ref': ref} if ref is not None else {}), 315 **({'country ': country} if country is not None else {}), 316 }) 317 318 if not is_json(response): 319 return response 320 321 return json.loads(response) 322 323 324 async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int, 325 forward: str | None = None) -> SetActivationStatusResponse: 326 members = {member.value: member for member in SetActivationStatusResponse} 327 response = await self.__send_request('setStatus', params={ 328 'id': activation_id, 329 'status': status.value if isinstance(status, SetActivationStatus) else status, 330 **({'forward': forward} if forward is not None else {}) 331 }) 332 333 return members[response] 334 335 async def get_history(self, 336 start: str | int = None, 337 end: str | int = None, 338 offset: str | int = None, 339 limit: str | int = None, 340 ) -> dict | list: 341 response = await self.__send_request('getHistory', params={ 342 **({'start': str(start)} if start is not None else {}), 343 **({'end': str(end)} if end is not None else {}), 344 **({'offset': str(offset)} if offset is not None else {}), 345 **({'limit': str(limit)} if limit is not None else {}), 346 }) 347 348 if not is_json(response): 349 return response 350 351 return json.loads(response) 352 353 async def get_list_top_countries(self, 354 service: str, 355 ) -> dict | list: 356 response = await self.__send_request('getListOfTopCountriesByService', params={ 357 'service': service 358 }) 359 360 if not is_json(response): 361 return response 362 363 return json.loads(response) 364 365 async def get_incoming_call_status(self, 366 id: str | int = None, 367 ) -> dict | list: 368 response = await self.__send_request('getIncomingCallStatus', params={ 369 'activationId': id 370 }) 371 372 if not is_json(response): 373 return response 374 375 return json.loads(response) 376 377 async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'): 378 """ 379 RU 380 Получить все данные о сервисе 381 EN 382 Get all data about service 383 384 Example 385 ```python 386 service = await sa.get_service('ya', 0) 387 print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075 388 ``` 389 """ 390 391 country = str(country) 392 name = await self.get_service_name(service_code, lang) 393 data = await self.get_prices(service_code, country) 394 395 cost = data[country][service_code]['cost'] 396 count = data[country][service_code]['count'] 397 physical_count = data[country][service_code]['physicalCount'] 398 return Service( 399 code=service_code, 400 country=country, 401 name=name, 402 cost=cost, 403 count=count, 404 physical_count=physical_count, 405 ) 406 407 async def get_prices(self, 408 service: str = None, 409 country: str | int = None, 410 ) -> dict | list: 411 response = await self.__send_request('getPrices', params={ 412 **({'service': str(service)} if service is not None else {}), 413 **({'country': str(country)} if country is not None else {}), 414 }) 415 416 if not is_json(response): 417 return response 418 419 return json.loads(response) 420 421 async def _get_service_cost(self, service: str, country: str | int): 422 data = await self.get_prices(service, country) 423 return data[country][service]['cost'] 424 425 async def _get_service_quantity(self, service: str, country: str | int): 426 data = await self.get_prices(service, country) 427 return data[country][service]['count'] 428 429 async def get_prices_verification(self, 430 service: str = None, 431 ) -> dict | list: 432 response = await self.__send_request('getPricesVerification', params={ 433 **({'service': str(service)} if service is not None else {}), 434 }) 435 436 if not is_json(response): 437 return response 438 439 return json.loads(response) 440 441 async def get_countries(self, 442 ) -> dict | list: 443 response = await self.__send_request('getCountries', params={ 444 }) 445 446 if not is_json(response): 447 return response 448 449 return json.loads(response) 450 451 @cached(cache) 452 async def get_service_list(self, 453 country: str = None, 454 lang: Literal['ru', 'en', 'es', 'cn'] = None, 455 ) -> dict | list: 456 response = await self.__send_request('getServicesList', params={ 457 **({'country': str(country)} if country is not None else {}), 458 **({'lang': str(lang)} if lang is not None else {}), 459 }) 460 461 if not is_json(response): 462 return response 463 464 return json.loads(response) 465 466 async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None): 467 """ 468 RU 469 Получение полного имени сервиса по его id 470 471 EN 472 Get full service name by service code 473 474 Пример Example: 475 service_name = await SmsActivate.get_service_name('go') 476 service_name # 'Google,youtube,Gmail' 477 """ 478 services = await self.get_service_list(lang=lang) 479 services = services.get('services') 480 for service in services: 481 if service['code'] == service_code: 482 return service['name'] 483 return None 484 485 async def get_additional_service(self, 486 service: str = None, 487 id: str = None, 488 ): 489 """ 490 Get additional service to activation its cost 5rub 491 return 2 values: addition activation id and phone number 492 493 use like this: 494 activation_id, phone_number = await getAdditionalService(service, activation id) 495 """ 496 response = await self.__send_request('getAdditionalService', params={ 497 'service': service, 498 'id':id 499 }) 500 501 data = response.split(':') 502 if len(data) > 2: 503 return data[1], data[2] 504 505 return data 506 507 async def get_extra_activation(self, 508 id: str = None, 509 ): 510 """ 511 return 2 values: addition activation id and phone number 512 513 use like this: 514 activation_id, phone_number = await getExtraActivation(activation id) 515 """ 516 response = await self.__send_request('getExtraActivation', params={ 517 'id':id 518 }) 519 520 data = response.split(':') 521 if len(data) > 2: 522 return data[1], data[2] 523 524 return data 525 526 async def check_extra_activation(self, 527 activationId: str | int 528 ) -> dict | list: 529 response = await self.__send_request('checkExtraActivation', params={ 530 'activationId': str(activationId) 531 }) 532 533 if not is_json(response): 534 return response 535 536 return json.loads(response) 537 538 async def parse_call(self, 539 id: str | int, 540 newLang: str, 541 ) -> dict | list: 542 response = await self.__send_request('parseCall', params={ 543 "id": id, 544 "newLang": newLang, 545 }) 546 547 if not is_json(response): 548 return response 549 550 return json.loads(response) 551 552 # !!! BOTTOM IT IS RENT API 553 async def get_rent_services_and_countries(self, 554 time: int | str | None = None, 555 operator: str | None = None, 556 country: str | None = None, 557 currency: str | None = None, 558 incomingCall: bool | None = None, 559 ) -> dict | str: 560 response = await self.__send_request('getRentServicesAndCountries', params={ 561 **({'time ': str(time )} if time is not None else {}), 562 **({'operator ': str(operator )} if operator is not None else {}), 563 **({'country ': str(country )} if country is not None else {}), 564 **({'currency ': str(currency )} if currency is not None else {}), 565 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 566 }) 567 568 if not is_json(response): 569 return response 570 571 return json.loads(response) 572 573 async def get_rent_number(self, 574 service: str, 575 time: int | str | None = None, 576 operator: str | None = None, 577 country: str | None = None, 578 url: str | None = None, 579 incomingCall: bool | None = None, 580 ) -> dict | str: 581 response = await self.__send_request('getRentNumber', params={ 582 'service': service, 583 **({'time ': str(time )} if time is not None else {}), 584 **({'operator ': str(operator )} if operator is not None else {}), 585 **({'country ': str(country )} if country is not None else {}), 586 **({'url ': str(url )} if url is not None else {}), 587 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 588 }) 589 590 if not is_json(response): 591 return response 592 593 return json.loads(response) 594 595 async def get_rent_status(self, 596 id: str, 597 page: int | str | None = None, 598 size: int | str | None = None, 599 ) -> dict | str: 600 response = await self.__send_request('getRentStatus', params={ 601 'id': id, 602 **({'page ': str(page)} if page is not None else {}), 603 **({'size ': str(size )} if size is not None else {}), 604 }) 605 606 if not is_json(response): 607 return response 608 609 return json.loads(response) 610 611 async def set_rent_status(self, 612 id: str, 613 status: Literal[1, 2, '1', '2'], 614 ) -> dict | str: 615 response = await self.__send_request('getRentStatus', params={ 616 'id': str(id), 617 'status': str(status), 618 }) 619 620 if not is_json(response): 621 return response 622 623 return json.loads(response) 624 625 async def get_rent_list(self, 626 ) -> dict | str: 627 response = await self.__send_request('getRentList', params={ 628 }) 629 630 if not is_json(response): 631 return response 632 633 return json.loads(response) 634 635 async def continue_rent_number(self, 636 id: str, 637 rent_time: int | str | None = 4, 638 ) -> dict | str: 639 response = await self.__send_request('continueRentNumber', params={ 640 'id': id, 641 'rent_time': str(rent_time) 642 }) 643 644 if not is_json(response): 645 return response 646 647 return json.loads(response) 648 649 async def get_continue_rent_price_number(self, 650 id: str, 651 rent_time: int | str | None = 4, 652 currency: str | None = None 653 ) -> dict | str: 654 response = await self.__send_request('getContinueRentPriceNumber', params={ 655 'id': id, 656 'rent_time': str(rent_time), 657 **({'currency ': str(currency )} if currency is not None else {}), 658 }) 659 660 if not is_json(response): 661 return response 662 663 return json.loads(response) 664 665 # !!! BOTTOM IS IT PARTNER SOFT API 666 async def buy_partner_product(self, 667 id: str, 668 ) -> dict | str: 669 response = await self.__send_request('buyPartnerProduct', params={ 670 'id': id, 671 }) 672 673 if not is_json(response): 674 return response 675 676 return json.loads(response) 677 678 679# === Method Aliases (outside class for pdoc) === 680SmsActivate.getBalance = SmsActivate.get_balance 681SmsActivate.getBalanceAndCashBack = SmsActivate.get_balance_and_cashback 682SmsActivate.getTopCountriesByService = SmsActivate.get_available_countries 683SmsActivate.getNumbersStatus = SmsActivate.get_count_numbers 684SmsActivate.getOperators = SmsActivate.get_operators 685SmsActivate.getActiveActivations = SmsActivate.get_active_activations 686SmsActivate.getStatus = SmsActivate.get_activation_status_v1 687SmsActivate.getStatusV2 = SmsActivate.get_activation_status 688SmsActivate.getNumberV2 = SmsActivate.purchase 689SmsActivate.purchase_v1 = SmsActivate.get_number 690SmsActivate.getNumber = SmsActivate.get_number 691SmsActivate.getMultiServiceNumber = SmsActivate.get_multi_service_number 692SmsActivate.setStatus = SmsActivate.set_activation_status 693SmsActivate.getHistory = SmsActivate.get_history 694SmsActivate.getListOfTopCountriesByService = SmsActivate.get_list_top_countries 695SmsActivate.getIncomingCallStatus = SmsActivate.get_incoming_call_status 696SmsActivate.getPrices = SmsActivate.get_prices 697SmsActivate.getPricesVerification = SmsActivate.get_prices_verification 698SmsActivate.getCountries = SmsActivate.get_countries 699SmsActivate.getServicesList = SmsActivate.get_service_list 700SmsActivate.getAdditionalService = SmsActivate.get_additional_service 701SmsActivate.getExtraActivation = SmsActivate.get_extra_activation 702SmsActivate.checkExtraActivation = SmsActivate.check_extra_activation 703SmsActivate.parseCall = SmsActivate.parse_call 704SmsActivate.getRentServicesAndCountries = SmsActivate.get_rent_services_and_countries 705SmsActivate.getRentNumber = SmsActivate.get_rent_number 706SmsActivate.getRentStatus = SmsActivate.get_rent_status 707SmsActivate.getRentStatus = SmsActivate.get_rent_status 708SmsActivate.getRentList = SmsActivate.get_rent_list 709SmsActivate.continueRentNumber = SmsActivate.continue_rent_number 710SmsActivate.getContinueRentPriceNumber = SmsActivate.get_continue_rent_price_number 711SmsActivate.buyPartnerProduct = SmsActivate.buy_partner_product
31class SmsActivate: 32 """ 33 RU 34 Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки 35 36 ВАЖНО 37 библиотека полностью поддерживает все методы с оффициальной документации 38 https://sms-activate.page/api2 на момент 08.07.2025 39 40 на git: https://github.com/AioSmsProviders/aiosmsactivate 41 Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi 42 или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof 43 44 EN 45 Thank you for using my library, you can participate in the development of the library. 46 47 important 48 The library fully supports all methods from the official documentation 49 https://sms-activate.page/api2 as of 07/08/2025 50 51 on git: https://github.com/AioSmsProviders/aiosmsactivate 52 You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi 53 or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof 54 55 SIMPLE USAGE 56 ```python 57 from aiosmsactivate import SmsActivate 58 from aiosmsactivate.types import SetActivationStatus 59 60 import asyncio 61 62 63 sa = SmsActivate('token') 64 65 async def main(): 66 balance = await sa.get_balance() 67 print(balance) # 6.25 68 69 number = await sa.purchase('ya') 70 number.activation_id # 3807035855 71 number.phone_number # '79238944456' 72 number.operator # 'mtt' 73 print(number) 74 # activation_id=3807035855 phone_number='79238944456' activation_cost=0.2 75 # country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27' 76 # operator='mtt' 77 78 code = await number.wait_sms_code(timeout=300) 79 print(code) # 1234 80 81 status = await number.get_activation_status() 82 83 await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number 84 await number.set_activation_status(8) # Отменить номер || Cancel number 85 86 asyncio.run(main()) 87 ``` 88 """ 89 90 def __init__(self, api_key: str, base_url: str | list = allowed_domains): 91 """ 92 RU 93 api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile 94 В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий 95 а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains 96 97 EN 98 api_key to transfer the api key, you can get it here: https://sms-activate.page/profile 99 You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one. 100 or you can specify one or not at all, if not specified, it will be taken from allowed_domains. 101 """ 102 self._api_key = api_key 103 if isinstance(base_url, str): 104 base_url = [base_url] 105 self._base_urls = base_url 106 self._accept_url = None 107 108 async def __send_request(self, action: str, **kwargs): 109 last_exception = None 110 111 for url in self._base_urls: 112 try: 113 url = self._accept_url if self._accept_url else url 114 params = None 115 if 'params' in kwargs.keys(): 116 params = kwargs.pop('params') 117 async with aiohttp.ClientSession() as session: 118 async with session.request( 119 'POST', 120 url, 121 **kwargs, 122 params={ 123 'api_key': self._api_key, 124 'action': action, 125 **(params if params else {}) 126 } 127 ) as response: 128 response.raise_for_status() 129 resp_text = await response.text() 130 raise_smsactivate_error(resp_text) 131 logging.debug(response.real_url) 132 return resp_text 133 except Exception as e: 134 last_exception = e 135 continue 136 self._accept_url = url 137 break 138 139 raise last_exception 140 141 async def get_balance(self, cashback: bool = False) -> float: 142 pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})') 143 response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack') 144 match = pattern.match(response) 145 if not match: 146 raise SmsActivateException('Invalid response sequence') 147 148 return float(match.group(1)) 149 async def get_balance_and_cashback(self): 150 return await self.get_balance(cashback=True) 151 152 async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]: 153 response = await self.__send_request('getTopCountriesByService', params={ 154 'service': service, 155 'freePrice': str(freePrice).lower() 156 }) 157 158 if not is_json(response): 159 return response 160 161 return json.loads(response) 162 163 async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]: 164 response = await self.__send_request('getNumbersStatus', params={ 165 'country': country, 166 'operator': operator 167 }) 168 169 if not is_json(response): 170 return response 171 172 return json.loads(response) 173 174 async def get_operators(self, country: str = None) -> dict[str, Any]: 175 params = {} 176 if country is not None: 177 params["country"] = country 178 response = await self.__send_request('getOperators', params=params) 179 180 if not is_json(response): 181 return response 182 183 return json.loads(response) 184 185 async def get_active_activations(self) -> dict[str, Any]: 186 response = await self.__send_request('getActiveActivations') 187 188 if not is_json(response): 189 return response 190 191 return json.loads(response) 192 193 async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]: 194 response = await self.__send_request('getStatus', params={ 195 'id': id 196 }) 197 198 data = response.split(':') 199 200 match data[0]: 201 case 'STATUS_WAIT_CODE': 202 return ActivationStatus.WAIT, None 203 case 'STATUS_WAIT_RETRY': 204 return ActivationStatus.RETRY, data[1] 205 case 'STATUS_WAIT_RESEND': 206 return ActivationStatus.RESEND, None 207 case 'STATUS_CANCEL': 208 return ActivationStatus.CANCEL, None 209 case 'STATUS_OK': 210 return ActivationStatus.OK, data[1] 211 case _: 212 raise SmsActivateException('Invalid response sequence') 213 214 async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str: 215 if isinstance(activation_id, Number): 216 activation_id = activation_id.activation_id 217 response = await self.__send_request('getStatusV2', params={ 218 'id': activation_id 219 }) 220 221 if not is_json(response): 222 return response 223 224 return ActivationData(**json.loads(response)) 225 226 async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None: 227 """ 228 Ожидание смс кода 229 Wait sms code 230 231 Аргументы: 232 activation_id: activation_id номера или целый объект номера 233 timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 234 per_attempt: время между попыткой получить смс, по умолчанию 5 секунд 235 236 Args: 237 activation_id: activation_id of number or Number object 238 timeout: maximum time to wait sms code 239 per_attempt: time per attempt 240 241 Returns: Sms 242 """ 243 activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id 244 if not self._api_key: 245 raise ValueError('API key is required for this method') 246 247 try: 248 await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY) 249 except: 250 pass 251 252 start_time = time.time() 253 254 while time.time() - start_time < timeout: 255 await asyncio.sleep(per_attempt) 256 status, code = await self.get_activation_status_v1(activation_id) 257 if status == ActivationStatus.OK: 258 try: 259 await self.set_activation_status(activation_id, SetActivationStatus.AGAIN) 260 except: 261 pass 262 return code 263 264 return None 265 266 async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None, 267 phoneException: str | None = None, operator: str | None = None, 268 activationType: int | str | None = None, language: str | None = None, 269 userId: str | int | None = None, 270 ref: str | None = None, country: str | None = None, 271 useCashBack: bool | None = None, 272 orderId: str | int | None = None, 273 _is_v2: bool = True 274 ) -> Number | str: 275 response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={ 276 'service': service, 277 **({'forward': 1 if forward else 0} if forward is not None else {}), 278 **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}), 279 **({'phoneException': phoneException} if phoneException is not None else {}), 280 **({'operator': operator} if operator is not None else {}), 281 **({'activationType': str(activationType)} if activationType is not None else {}), 282 **({'language': str(language)} if language is not None else {}), 283 **({'userId': str(userId)} if userId is not None else {}), 284 **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}), 285 **({'ref': ref} if ref is not None else {}), 286 **({'country ': country} if country is not None else {}), 287 **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}), 288 }) 289 290 if not is_json(response): 291 return response 292 293 return Number.from_response(self, json.loads(response)) 294 295 async def get_number(self, *args, **kwargs): 296 kwargs["_is_v2"] = False 297 return await self.purchase(*args, **kwargs) 298 299 async def get_multi_service_number(self, 300 multiService: str, multiForward: str | None = None, 301 operator: str | None = None, 302 ref: str | None = None, country: str | None = None, 303 ) -> dict: 304 """ 305 Get multiservice number. 306 307 :param multiService: service1,service2,service3 (Services separated by commas) 308 :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count) 309 :return: dict object of response 310 """ 311 response = await self.__send_request('getMultiServiceNumber', params={ 312 'multiService': multiService, 313 **({'multiForward': multiForward} if multiForward is not None else {}), 314 **({'operator': operator} if operator is not None else {}), 315 **({'ref': ref} if ref is not None else {}), 316 **({'country ': country} if country is not None else {}), 317 }) 318 319 if not is_json(response): 320 return response 321 322 return json.loads(response) 323 324 325 async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int, 326 forward: str | None = None) -> SetActivationStatusResponse: 327 members = {member.value: member for member in SetActivationStatusResponse} 328 response = await self.__send_request('setStatus', params={ 329 'id': activation_id, 330 'status': status.value if isinstance(status, SetActivationStatus) else status, 331 **({'forward': forward} if forward is not None else {}) 332 }) 333 334 return members[response] 335 336 async def get_history(self, 337 start: str | int = None, 338 end: str | int = None, 339 offset: str | int = None, 340 limit: str | int = None, 341 ) -> dict | list: 342 response = await self.__send_request('getHistory', params={ 343 **({'start': str(start)} if start is not None else {}), 344 **({'end': str(end)} if end is not None else {}), 345 **({'offset': str(offset)} if offset is not None else {}), 346 **({'limit': str(limit)} if limit is not None else {}), 347 }) 348 349 if not is_json(response): 350 return response 351 352 return json.loads(response) 353 354 async def get_list_top_countries(self, 355 service: str, 356 ) -> dict | list: 357 response = await self.__send_request('getListOfTopCountriesByService', params={ 358 'service': service 359 }) 360 361 if not is_json(response): 362 return response 363 364 return json.loads(response) 365 366 async def get_incoming_call_status(self, 367 id: str | int = None, 368 ) -> dict | list: 369 response = await self.__send_request('getIncomingCallStatus', params={ 370 'activationId': id 371 }) 372 373 if not is_json(response): 374 return response 375 376 return json.loads(response) 377 378 async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'): 379 """ 380 RU 381 Получить все данные о сервисе 382 EN 383 Get all data about service 384 385 Example 386 ```python 387 service = await sa.get_service('ya', 0) 388 print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075 389 ``` 390 """ 391 392 country = str(country) 393 name = await self.get_service_name(service_code, lang) 394 data = await self.get_prices(service_code, country) 395 396 cost = data[country][service_code]['cost'] 397 count = data[country][service_code]['count'] 398 physical_count = data[country][service_code]['physicalCount'] 399 return Service( 400 code=service_code, 401 country=country, 402 name=name, 403 cost=cost, 404 count=count, 405 physical_count=physical_count, 406 ) 407 408 async def get_prices(self, 409 service: str = None, 410 country: str | int = None, 411 ) -> dict | list: 412 response = await self.__send_request('getPrices', params={ 413 **({'service': str(service)} if service is not None else {}), 414 **({'country': str(country)} if country is not None else {}), 415 }) 416 417 if not is_json(response): 418 return response 419 420 return json.loads(response) 421 422 async def _get_service_cost(self, service: str, country: str | int): 423 data = await self.get_prices(service, country) 424 return data[country][service]['cost'] 425 426 async def _get_service_quantity(self, service: str, country: str | int): 427 data = await self.get_prices(service, country) 428 return data[country][service]['count'] 429 430 async def get_prices_verification(self, 431 service: str = None, 432 ) -> dict | list: 433 response = await self.__send_request('getPricesVerification', params={ 434 **({'service': str(service)} if service is not None else {}), 435 }) 436 437 if not is_json(response): 438 return response 439 440 return json.loads(response) 441 442 async def get_countries(self, 443 ) -> dict | list: 444 response = await self.__send_request('getCountries', params={ 445 }) 446 447 if not is_json(response): 448 return response 449 450 return json.loads(response) 451 452 @cached(cache) 453 async def get_service_list(self, 454 country: str = None, 455 lang: Literal['ru', 'en', 'es', 'cn'] = None, 456 ) -> dict | list: 457 response = await self.__send_request('getServicesList', params={ 458 **({'country': str(country)} if country is not None else {}), 459 **({'lang': str(lang)} if lang is not None else {}), 460 }) 461 462 if not is_json(response): 463 return response 464 465 return json.loads(response) 466 467 async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None): 468 """ 469 RU 470 Получение полного имени сервиса по его id 471 472 EN 473 Get full service name by service code 474 475 Пример Example: 476 service_name = await SmsActivate.get_service_name('go') 477 service_name # 'Google,youtube,Gmail' 478 """ 479 services = await self.get_service_list(lang=lang) 480 services = services.get('services') 481 for service in services: 482 if service['code'] == service_code: 483 return service['name'] 484 return None 485 486 async def get_additional_service(self, 487 service: str = None, 488 id: str = None, 489 ): 490 """ 491 Get additional service to activation its cost 5rub 492 return 2 values: addition activation id and phone number 493 494 use like this: 495 activation_id, phone_number = await getAdditionalService(service, activation id) 496 """ 497 response = await self.__send_request('getAdditionalService', params={ 498 'service': service, 499 'id':id 500 }) 501 502 data = response.split(':') 503 if len(data) > 2: 504 return data[1], data[2] 505 506 return data 507 508 async def get_extra_activation(self, 509 id: str = None, 510 ): 511 """ 512 return 2 values: addition activation id and phone number 513 514 use like this: 515 activation_id, phone_number = await getExtraActivation(activation id) 516 """ 517 response = await self.__send_request('getExtraActivation', params={ 518 'id':id 519 }) 520 521 data = response.split(':') 522 if len(data) > 2: 523 return data[1], data[2] 524 525 return data 526 527 async def check_extra_activation(self, 528 activationId: str | int 529 ) -> dict | list: 530 response = await self.__send_request('checkExtraActivation', params={ 531 'activationId': str(activationId) 532 }) 533 534 if not is_json(response): 535 return response 536 537 return json.loads(response) 538 539 async def parse_call(self, 540 id: str | int, 541 newLang: str, 542 ) -> dict | list: 543 response = await self.__send_request('parseCall', params={ 544 "id": id, 545 "newLang": newLang, 546 }) 547 548 if not is_json(response): 549 return response 550 551 return json.loads(response) 552 553 # !!! BOTTOM IT IS RENT API 554 async def get_rent_services_and_countries(self, 555 time: int | str | None = None, 556 operator: str | None = None, 557 country: str | None = None, 558 currency: str | None = None, 559 incomingCall: bool | None = None, 560 ) -> dict | str: 561 response = await self.__send_request('getRentServicesAndCountries', params={ 562 **({'time ': str(time )} if time is not None else {}), 563 **({'operator ': str(operator )} if operator is not None else {}), 564 **({'country ': str(country )} if country is not None else {}), 565 **({'currency ': str(currency )} if currency is not None else {}), 566 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 567 }) 568 569 if not is_json(response): 570 return response 571 572 return json.loads(response) 573 574 async def get_rent_number(self, 575 service: str, 576 time: int | str | None = None, 577 operator: str | None = None, 578 country: str | None = None, 579 url: str | None = None, 580 incomingCall: bool | None = None, 581 ) -> dict | str: 582 response = await self.__send_request('getRentNumber', params={ 583 'service': service, 584 **({'time ': str(time )} if time is not None else {}), 585 **({'operator ': str(operator )} if operator is not None else {}), 586 **({'country ': str(country )} if country is not None else {}), 587 **({'url ': str(url )} if url is not None else {}), 588 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 589 }) 590 591 if not is_json(response): 592 return response 593 594 return json.loads(response) 595 596 async def get_rent_status(self, 597 id: str, 598 page: int | str | None = None, 599 size: int | str | None = None, 600 ) -> dict | str: 601 response = await self.__send_request('getRentStatus', params={ 602 'id': id, 603 **({'page ': str(page)} if page is not None else {}), 604 **({'size ': str(size )} if size is not None else {}), 605 }) 606 607 if not is_json(response): 608 return response 609 610 return json.loads(response) 611 612 async def set_rent_status(self, 613 id: str, 614 status: Literal[1, 2, '1', '2'], 615 ) -> dict | str: 616 response = await self.__send_request('getRentStatus', params={ 617 'id': str(id), 618 'status': str(status), 619 }) 620 621 if not is_json(response): 622 return response 623 624 return json.loads(response) 625 626 async def get_rent_list(self, 627 ) -> dict | str: 628 response = await self.__send_request('getRentList', params={ 629 }) 630 631 if not is_json(response): 632 return response 633 634 return json.loads(response) 635 636 async def continue_rent_number(self, 637 id: str, 638 rent_time: int | str | None = 4, 639 ) -> dict | str: 640 response = await self.__send_request('continueRentNumber', params={ 641 'id': id, 642 'rent_time': str(rent_time) 643 }) 644 645 if not is_json(response): 646 return response 647 648 return json.loads(response) 649 650 async def get_continue_rent_price_number(self, 651 id: str, 652 rent_time: int | str | None = 4, 653 currency: str | None = None 654 ) -> dict | str: 655 response = await self.__send_request('getContinueRentPriceNumber', params={ 656 'id': id, 657 'rent_time': str(rent_time), 658 **({'currency ': str(currency )} if currency is not None else {}), 659 }) 660 661 if not is_json(response): 662 return response 663 664 return json.loads(response) 665 666 # !!! BOTTOM IS IT PARTNER SOFT API 667 async def buy_partner_product(self, 668 id: str, 669 ) -> dict | str: 670 response = await self.__send_request('buyPartnerProduct', params={ 671 'id': id, 672 }) 673 674 if not is_json(response): 675 return response 676 677 return json.loads(response)
RU
Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки
ВАЖНО библиотека полностью поддерживает все методы с оффициальной документации https://sms-activate.page/api2 на момент 08.07.2025
на git: https://github.com/AioSmsProviders/aiosmsactivate Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof
EN
Thank you for using my library, you can participate in the development of the library.
important The library fully supports all methods from the official documentation https://sms-activate.page/api2 as of 07/08/2025
on git: https://github.com/AioSmsProviders/aiosmsactivate You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof
SIMPLE USAGE
from aiosmsactivate import SmsActivate
from aiosmsactivate.types import SetActivationStatus
import asyncio
sa = SmsActivate('token')
async def main():
balance = await sa.get_balance()
print(balance) # 6.25
number = await sa.purchase('ya')
number.activation_id # 3807035855
number.phone_number # '79238944456'
number.operator # 'mtt'
print(number)
# activation_id=3807035855 phone_number='79238944456' activation_cost=0.2
# country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27'
# operator='mtt'
code = await number.wait_sms_code(timeout=300)
print(code) # 1234
status = await number.get_activation_status()
await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number
await number.set_activation_status(8) # Отменить номер || Cancel number
asyncio.run(main())
90 def __init__(self, api_key: str, base_url: str | list = allowed_domains): 91 """ 92 RU 93 api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile 94 В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий 95 а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains 96 97 EN 98 api_key to transfer the api key, you can get it here: https://sms-activate.page/profile 99 You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one. 100 or you can specify one or not at all, if not specified, it will be taken from allowed_domains. 101 """ 102 self._api_key = api_key 103 if isinstance(base_url, str): 104 base_url = [base_url] 105 self._base_urls = base_url 106 self._accept_url = None
RU
api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile
В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий
а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains
EN
api_key to transfer the api key, you can get it here: https://sms-activate.page/profile
You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one.
or you can specify one or not at all, if not specified, it will be taken from allowed_domains.
141 async def get_balance(self, cashback: bool = False) -> float: 142 pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})') 143 response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack') 144 match = pattern.match(response) 145 if not match: 146 raise SmsActivateException('Invalid response sequence') 147 148 return float(match.group(1))
152 async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]: 153 response = await self.__send_request('getTopCountriesByService', params={ 154 'service': service, 155 'freePrice': str(freePrice).lower() 156 }) 157 158 if not is_json(response): 159 return response 160 161 return json.loads(response)
163 async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]: 164 response = await self.__send_request('getNumbersStatus', params={ 165 'country': country, 166 'operator': operator 167 }) 168 169 if not is_json(response): 170 return response 171 172 return json.loads(response)
174 async def get_operators(self, country: str = None) -> dict[str, Any]: 175 params = {} 176 if country is not None: 177 params["country"] = country 178 response = await self.__send_request('getOperators', params=params) 179 180 if not is_json(response): 181 return response 182 183 return json.loads(response)
193 async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]: 194 response = await self.__send_request('getStatus', params={ 195 'id': id 196 }) 197 198 data = response.split(':') 199 200 match data[0]: 201 case 'STATUS_WAIT_CODE': 202 return ActivationStatus.WAIT, None 203 case 'STATUS_WAIT_RETRY': 204 return ActivationStatus.RETRY, data[1] 205 case 'STATUS_WAIT_RESEND': 206 return ActivationStatus.RESEND, None 207 case 'STATUS_CANCEL': 208 return ActivationStatus.CANCEL, None 209 case 'STATUS_OK': 210 return ActivationStatus.OK, data[1] 211 case _: 212 raise SmsActivateException('Invalid response sequence')
214 async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str: 215 if isinstance(activation_id, Number): 216 activation_id = activation_id.activation_id 217 response = await self.__send_request('getStatusV2', params={ 218 'id': activation_id 219 }) 220 221 if not is_json(response): 222 return response 223 224 return ActivationData(**json.loads(response))
226 async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None: 227 """ 228 Ожидание смс кода 229 Wait sms code 230 231 Аргументы: 232 activation_id: activation_id номера или целый объект номера 233 timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 234 per_attempt: время между попыткой получить смс, по умолчанию 5 секунд 235 236 Args: 237 activation_id: activation_id of number or Number object 238 timeout: maximum time to wait sms code 239 per_attempt: time per attempt 240 241 Returns: Sms 242 """ 243 activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id 244 if not self._api_key: 245 raise ValueError('API key is required for this method') 246 247 try: 248 await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY) 249 except: 250 pass 251 252 start_time = time.time() 253 254 while time.time() - start_time < timeout: 255 await asyncio.sleep(per_attempt) 256 status, code = await self.get_activation_status_v1(activation_id) 257 if status == ActivationStatus.OK: 258 try: 259 await self.set_activation_status(activation_id, SetActivationStatus.AGAIN) 260 except: 261 pass 262 return code 263 264 return None
Ожидание смс кода Wait sms code
Аргументы: activation_id: activation_id номера или целый объект номера timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут per_attempt: время между попыткой получить смс, по умолчанию 5 секунд
Args: activation_id: activation_id of number or Number object timeout: maximum time to wait sms code per_attempt: time per attempt
Returns: Sms
266 async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None, 267 phoneException: str | None = None, operator: str | None = None, 268 activationType: int | str | None = None, language: str | None = None, 269 userId: str | int | None = None, 270 ref: str | None = None, country: str | None = None, 271 useCashBack: bool | None = None, 272 orderId: str | int | None = None, 273 _is_v2: bool = True 274 ) -> Number | str: 275 response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={ 276 'service': service, 277 **({'forward': 1 if forward else 0} if forward is not None else {}), 278 **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}), 279 **({'phoneException': phoneException} if phoneException is not None else {}), 280 **({'operator': operator} if operator is not None else {}), 281 **({'activationType': str(activationType)} if activationType is not None else {}), 282 **({'language': str(language)} if language is not None else {}), 283 **({'userId': str(userId)} if userId is not None else {}), 284 **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}), 285 **({'ref': ref} if ref is not None else {}), 286 **({'country ': country} if country is not None else {}), 287 **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}), 288 }) 289 290 if not is_json(response): 291 return response 292 293 return Number.from_response(self, json.loads(response))
299 async def get_multi_service_number(self, 300 multiService: str, multiForward: str | None = None, 301 operator: str | None = None, 302 ref: str | None = None, country: str | None = None, 303 ) -> dict: 304 """ 305 Get multiservice number. 306 307 :param multiService: service1,service2,service3 (Services separated by commas) 308 :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count) 309 :return: dict object of response 310 """ 311 response = await self.__send_request('getMultiServiceNumber', params={ 312 'multiService': multiService, 313 **({'multiForward': multiForward} if multiForward is not None else {}), 314 **({'operator': operator} if operator is not None else {}), 315 **({'ref': ref} if ref is not None else {}), 316 **({'country ': country} if country is not None else {}), 317 }) 318 319 if not is_json(response): 320 return response 321 322 return json.loads(response)
Get multiservice number.
Parameters
- multiService: service1,service2,service3 (Services separated by commas)
- multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
Returns
dict object of response
325 async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int, 326 forward: str | None = None) -> SetActivationStatusResponse: 327 members = {member.value: member for member in SetActivationStatusResponse} 328 response = await self.__send_request('setStatus', params={ 329 'id': activation_id, 330 'status': status.value if isinstance(status, SetActivationStatus) else status, 331 **({'forward': forward} if forward is not None else {}) 332 }) 333 334 return members[response]
336 async def get_history(self, 337 start: str | int = None, 338 end: str | int = None, 339 offset: str | int = None, 340 limit: str | int = None, 341 ) -> dict | list: 342 response = await self.__send_request('getHistory', params={ 343 **({'start': str(start)} if start is not None else {}), 344 **({'end': str(end)} if end is not None else {}), 345 **({'offset': str(offset)} if offset is not None else {}), 346 **({'limit': str(limit)} if limit is not None else {}), 347 }) 348 349 if not is_json(response): 350 return response 351 352 return json.loads(response)
378 async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'): 379 """ 380 RU 381 Получить все данные о сервисе 382 EN 383 Get all data about service 384 385 Example 386 ```python 387 service = await sa.get_service('ya', 0) 388 print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075 389 ``` 390 """ 391 392 country = str(country) 393 name = await self.get_service_name(service_code, lang) 394 data = await self.get_prices(service_code, country) 395 396 cost = data[country][service_code]['cost'] 397 count = data[country][service_code]['count'] 398 physical_count = data[country][service_code]['physicalCount'] 399 return Service( 400 code=service_code, 401 country=country, 402 name=name, 403 cost=cost, 404 count=count, 405 physical_count=physical_count, 406 )
RU
Получить все данные о сервисе
EN
Get all data about service
Example
service = await sa.get_service('ya', 0)
print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075
408 async def get_prices(self, 409 service: str = None, 410 country: str | int = None, 411 ) -> dict | list: 412 response = await self.__send_request('getPrices', params={ 413 **({'service': str(service)} if service is not None else {}), 414 **({'country': str(country)} if country is not None else {}), 415 }) 416 417 if not is_json(response): 418 return response 419 420 return json.loads(response)
430 async def get_prices_verification(self, 431 service: str = None, 432 ) -> dict | list: 433 response = await self.__send_request('getPricesVerification', params={ 434 **({'service': str(service)} if service is not None else {}), 435 }) 436 437 if not is_json(response): 438 return response 439 440 return json.loads(response)
452 @cached(cache) 453 async def get_service_list(self, 454 country: str = None, 455 lang: Literal['ru', 'en', 'es', 'cn'] = None, 456 ) -> dict | list: 457 response = await self.__send_request('getServicesList', params={ 458 **({'country': str(country)} if country is not None else {}), 459 **({'lang': str(lang)} if lang is not None else {}), 460 }) 461 462 if not is_json(response): 463 return response 464 465 return json.loads(response)
467 async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None): 468 """ 469 RU 470 Получение полного имени сервиса по его id 471 472 EN 473 Get full service name by service code 474 475 Пример Example: 476 service_name = await SmsActivate.get_service_name('go') 477 service_name # 'Google,youtube,Gmail' 478 """ 479 services = await self.get_service_list(lang=lang) 480 services = services.get('services') 481 for service in services: 482 if service['code'] == service_code: 483 return service['name'] 484 return None
RU
Получение полного имени сервиса по его id
EN
Get full service name by service code
Пример Example:
service_name = await SmsActivate.get_service_name('go')
service_name # 'Google,youtube,Gmail'
486 async def get_additional_service(self, 487 service: str = None, 488 id: str = None, 489 ): 490 """ 491 Get additional service to activation its cost 5rub 492 return 2 values: addition activation id and phone number 493 494 use like this: 495 activation_id, phone_number = await getAdditionalService(service, activation id) 496 """ 497 response = await self.__send_request('getAdditionalService', params={ 498 'service': service, 499 'id':id 500 }) 501 502 data = response.split(':') 503 if len(data) > 2: 504 return data[1], data[2] 505 506 return data
Get additional service to activation its cost 5rub return 2 values: addition activation id and phone number
use like this: activation_id, phone_number = await getAdditionalService(service, activation id)
508 async def get_extra_activation(self, 509 id: str = None, 510 ): 511 """ 512 return 2 values: addition activation id and phone number 513 514 use like this: 515 activation_id, phone_number = await getExtraActivation(activation id) 516 """ 517 response = await self.__send_request('getExtraActivation', params={ 518 'id':id 519 }) 520 521 data = response.split(':') 522 if len(data) > 2: 523 return data[1], data[2] 524 525 return data
return 2 values: addition activation id and phone number
use like this: activation_id, phone_number = await getExtraActivation(activation id)
527 async def check_extra_activation(self, 528 activationId: str | int 529 ) -> dict | list: 530 response = await self.__send_request('checkExtraActivation', params={ 531 'activationId': str(activationId) 532 }) 533 534 if not is_json(response): 535 return response 536 537 return json.loads(response)
554 async def get_rent_services_and_countries(self, 555 time: int | str | None = None, 556 operator: str | None = None, 557 country: str | None = None, 558 currency: str | None = None, 559 incomingCall: bool | None = None, 560 ) -> dict | str: 561 response = await self.__send_request('getRentServicesAndCountries', params={ 562 **({'time ': str(time )} if time is not None else {}), 563 **({'operator ': str(operator )} if operator is not None else {}), 564 **({'country ': str(country )} if country is not None else {}), 565 **({'currency ': str(currency )} if currency is not None else {}), 566 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 567 }) 568 569 if not is_json(response): 570 return response 571 572 return json.loads(response)
574 async def get_rent_number(self, 575 service: str, 576 time: int | str | None = None, 577 operator: str | None = None, 578 country: str | None = None, 579 url: str | None = None, 580 incomingCall: bool | None = None, 581 ) -> dict | str: 582 response = await self.__send_request('getRentNumber', params={ 583 'service': service, 584 **({'time ': str(time )} if time is not None else {}), 585 **({'operator ': str(operator )} if operator is not None else {}), 586 **({'country ': str(country )} if country is not None else {}), 587 **({'url ': str(url )} if url is not None else {}), 588 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 589 }) 590 591 if not is_json(response): 592 return response 593 594 return json.loads(response)
596 async def get_rent_status(self, 597 id: str, 598 page: int | str | None = None, 599 size: int | str | None = None, 600 ) -> dict | str: 601 response = await self.__send_request('getRentStatus', params={ 602 'id': id, 603 **({'page ': str(page)} if page is not None else {}), 604 **({'size ': str(size )} if size is not None else {}), 605 }) 606 607 if not is_json(response): 608 return response 609 610 return json.loads(response)
612 async def set_rent_status(self, 613 id: str, 614 status: Literal[1, 2, '1', '2'], 615 ) -> dict | str: 616 response = await self.__send_request('getRentStatus', params={ 617 'id': str(id), 618 'status': str(status), 619 }) 620 621 if not is_json(response): 622 return response 623 624 return json.loads(response)
636 async def continue_rent_number(self, 637 id: str, 638 rent_time: int | str | None = 4, 639 ) -> dict | str: 640 response = await self.__send_request('continueRentNumber', params={ 641 'id': id, 642 'rent_time': str(rent_time) 643 }) 644 645 if not is_json(response): 646 return response 647 648 return json.loads(response)
650 async def get_continue_rent_price_number(self, 651 id: str, 652 rent_time: int | str | None = 4, 653 currency: str | None = None 654 ) -> dict | str: 655 response = await self.__send_request('getContinueRentPriceNumber', params={ 656 'id': id, 657 'rent_time': str(rent_time), 658 **({'currency ': str(currency )} if currency is not None else {}), 659 }) 660 661 if not is_json(response): 662 return response 663 664 return json.loads(response)
141 async def get_balance(self, cashback: bool = False) -> float: 142 pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})') 143 response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack') 144 match = pattern.match(response) 145 if not match: 146 raise SmsActivateException('Invalid response sequence') 147 148 return float(match.group(1))
152 async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]: 153 response = await self.__send_request('getTopCountriesByService', params={ 154 'service': service, 155 'freePrice': str(freePrice).lower() 156 }) 157 158 if not is_json(response): 159 return response 160 161 return json.loads(response)
163 async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]: 164 response = await self.__send_request('getNumbersStatus', params={ 165 'country': country, 166 'operator': operator 167 }) 168 169 if not is_json(response): 170 return response 171 172 return json.loads(response)
174 async def get_operators(self, country: str = None) -> dict[str, Any]: 175 params = {} 176 if country is not None: 177 params["country"] = country 178 response = await self.__send_request('getOperators', params=params) 179 180 if not is_json(response): 181 return response 182 183 return json.loads(response)
193 async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]: 194 response = await self.__send_request('getStatus', params={ 195 'id': id 196 }) 197 198 data = response.split(':') 199 200 match data[0]: 201 case 'STATUS_WAIT_CODE': 202 return ActivationStatus.WAIT, None 203 case 'STATUS_WAIT_RETRY': 204 return ActivationStatus.RETRY, data[1] 205 case 'STATUS_WAIT_RESEND': 206 return ActivationStatus.RESEND, None 207 case 'STATUS_CANCEL': 208 return ActivationStatus.CANCEL, None 209 case 'STATUS_OK': 210 return ActivationStatus.OK, data[1] 211 case _: 212 raise SmsActivateException('Invalid response sequence')
214 async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str: 215 if isinstance(activation_id, Number): 216 activation_id = activation_id.activation_id 217 response = await self.__send_request('getStatusV2', params={ 218 'id': activation_id 219 }) 220 221 if not is_json(response): 222 return response 223 224 return ActivationData(**json.loads(response))
266 async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None, 267 phoneException: str | None = None, operator: str | None = None, 268 activationType: int | str | None = None, language: str | None = None, 269 userId: str | int | None = None, 270 ref: str | None = None, country: str | None = None, 271 useCashBack: bool | None = None, 272 orderId: str | int | None = None, 273 _is_v2: bool = True 274 ) -> Number | str: 275 response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={ 276 'service': service, 277 **({'forward': 1 if forward else 0} if forward is not None else {}), 278 **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}), 279 **({'phoneException': phoneException} if phoneException is not None else {}), 280 **({'operator': operator} if operator is not None else {}), 281 **({'activationType': str(activationType)} if activationType is not None else {}), 282 **({'language': str(language)} if language is not None else {}), 283 **({'userId': str(userId)} if userId is not None else {}), 284 **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}), 285 **({'ref': ref} if ref is not None else {}), 286 **({'country ': country} if country is not None else {}), 287 **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}), 288 }) 289 290 if not is_json(response): 291 return response 292 293 return Number.from_response(self, json.loads(response))
299 async def get_multi_service_number(self, 300 multiService: str, multiForward: str | None = None, 301 operator: str | None = None, 302 ref: str | None = None, country: str | None = None, 303 ) -> dict: 304 """ 305 Get multiservice number. 306 307 :param multiService: service1,service2,service3 (Services separated by commas) 308 :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count) 309 :return: dict object of response 310 """ 311 response = await self.__send_request('getMultiServiceNumber', params={ 312 'multiService': multiService, 313 **({'multiForward': multiForward} if multiForward is not None else {}), 314 **({'operator': operator} if operator is not None else {}), 315 **({'ref': ref} if ref is not None else {}), 316 **({'country ': country} if country is not None else {}), 317 }) 318 319 if not is_json(response): 320 return response 321 322 return json.loads(response)
Get multiservice number.
Parameters
- multiService: service1,service2,service3 (Services separated by commas)
- multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
Returns
dict object of response
325 async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int, 326 forward: str | None = None) -> SetActivationStatusResponse: 327 members = {member.value: member for member in SetActivationStatusResponse} 328 response = await self.__send_request('setStatus', params={ 329 'id': activation_id, 330 'status': status.value if isinstance(status, SetActivationStatus) else status, 331 **({'forward': forward} if forward is not None else {}) 332 }) 333 334 return members[response]
336 async def get_history(self, 337 start: str | int = None, 338 end: str | int = None, 339 offset: str | int = None, 340 limit: str | int = None, 341 ) -> dict | list: 342 response = await self.__send_request('getHistory', params={ 343 **({'start': str(start)} if start is not None else {}), 344 **({'end': str(end)} if end is not None else {}), 345 **({'offset': str(offset)} if offset is not None else {}), 346 **({'limit': str(limit)} if limit is not None else {}), 347 }) 348 349 if not is_json(response): 350 return response 351 352 return json.loads(response)
408 async def get_prices(self, 409 service: str = None, 410 country: str | int = None, 411 ) -> dict | list: 412 response = await self.__send_request('getPrices', params={ 413 **({'service': str(service)} if service is not None else {}), 414 **({'country': str(country)} if country is not None else {}), 415 }) 416 417 if not is_json(response): 418 return response 419 420 return json.loads(response)
430 async def get_prices_verification(self, 431 service: str = None, 432 ) -> dict | list: 433 response = await self.__send_request('getPricesVerification', params={ 434 **({'service': str(service)} if service is not None else {}), 435 }) 436 437 if not is_json(response): 438 return response 439 440 return json.loads(response)
452 @cached(cache) 453 async def get_service_list(self, 454 country: str = None, 455 lang: Literal['ru', 'en', 'es', 'cn'] = None, 456 ) -> dict | list: 457 response = await self.__send_request('getServicesList', params={ 458 **({'country': str(country)} if country is not None else {}), 459 **({'lang': str(lang)} if lang is not None else {}), 460 }) 461 462 if not is_json(response): 463 return response 464 465 return json.loads(response)
486 async def get_additional_service(self, 487 service: str = None, 488 id: str = None, 489 ): 490 """ 491 Get additional service to activation its cost 5rub 492 return 2 values: addition activation id and phone number 493 494 use like this: 495 activation_id, phone_number = await getAdditionalService(service, activation id) 496 """ 497 response = await self.__send_request('getAdditionalService', params={ 498 'service': service, 499 'id':id 500 }) 501 502 data = response.split(':') 503 if len(data) > 2: 504 return data[1], data[2] 505 506 return data
Get additional service to activation its cost 5rub return 2 values: addition activation id and phone number
use like this: activation_id, phone_number = await getAdditionalService(service, activation id)
508 async def get_extra_activation(self, 509 id: str = None, 510 ): 511 """ 512 return 2 values: addition activation id and phone number 513 514 use like this: 515 activation_id, phone_number = await getExtraActivation(activation id) 516 """ 517 response = await self.__send_request('getExtraActivation', params={ 518 'id':id 519 }) 520 521 data = response.split(':') 522 if len(data) > 2: 523 return data[1], data[2] 524 525 return data
return 2 values: addition activation id and phone number
use like this: activation_id, phone_number = await getExtraActivation(activation id)
527 async def check_extra_activation(self, 528 activationId: str | int 529 ) -> dict | list: 530 response = await self.__send_request('checkExtraActivation', params={ 531 'activationId': str(activationId) 532 }) 533 534 if not is_json(response): 535 return response 536 537 return json.loads(response)
554 async def get_rent_services_and_countries(self, 555 time: int | str | None = None, 556 operator: str | None = None, 557 country: str | None = None, 558 currency: str | None = None, 559 incomingCall: bool | None = None, 560 ) -> dict | str: 561 response = await self.__send_request('getRentServicesAndCountries', params={ 562 **({'time ': str(time )} if time is not None else {}), 563 **({'operator ': str(operator )} if operator is not None else {}), 564 **({'country ': str(country )} if country is not None else {}), 565 **({'currency ': str(currency )} if currency is not None else {}), 566 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 567 }) 568 569 if not is_json(response): 570 return response 571 572 return json.loads(response)
574 async def get_rent_number(self, 575 service: str, 576 time: int | str | None = None, 577 operator: str | None = None, 578 country: str | None = None, 579 url: str | None = None, 580 incomingCall: bool | None = None, 581 ) -> dict | str: 582 response = await self.__send_request('getRentNumber', params={ 583 'service': service, 584 **({'time ': str(time )} if time is not None else {}), 585 **({'operator ': str(operator )} if operator is not None else {}), 586 **({'country ': str(country )} if country is not None else {}), 587 **({'url ': str(url )} if url is not None else {}), 588 **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}), 589 }) 590 591 if not is_json(response): 592 return response 593 594 return json.loads(response)
596 async def get_rent_status(self, 597 id: str, 598 page: int | str | None = None, 599 size: int | str | None = None, 600 ) -> dict | str: 601 response = await self.__send_request('getRentStatus', params={ 602 'id': id, 603 **({'page ': str(page)} if page is not None else {}), 604 **({'size ': str(size )} if size is not None else {}), 605 }) 606 607 if not is_json(response): 608 return response 609 610 return json.loads(response)
636 async def continue_rent_number(self, 637 id: str, 638 rent_time: int | str | None = 4, 639 ) -> dict | str: 640 response = await self.__send_request('continueRentNumber', params={ 641 'id': id, 642 'rent_time': str(rent_time) 643 }) 644 645 if not is_json(response): 646 return response 647 648 return json.loads(response)
650 async def get_continue_rent_price_number(self, 651 id: str, 652 rent_time: int | str | None = 4, 653 currency: str | None = None 654 ) -> dict | str: 655 response = await self.__send_request('getContinueRentPriceNumber', params={ 656 'id': id, 657 'rent_time': str(rent_time), 658 **({'currency ': str(currency )} if currency is not None else {}), 659 }) 660 661 if not is_json(response): 662 return response 663 664 return json.loads(response)