Skip to content

Commit

Permalink
Android User-Agent
Browse files Browse the repository at this point in the history
  • Loading branch information
gentslava committed Nov 13, 2024
1 parent 6f2f82b commit 1fe7a6d
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 98 deletions.
21 changes: 9 additions & 12 deletions custom_components/elektronny_gorod/api.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
from aiohttp import ClientSession, ClientError
import json
from .helpers import (
is_json,
generate_user_agent
)
from .helpers import is_json
from .const import (
LOGGER,
BASE_API_URL,
)

from .user_agent import UserAgent

class ElektronnyGorodAPI:
def __init__(
self,
user_agent: UserAgent,
access_token: str | None = None,
refresh_token: str | None = None,
headers: dict = {}
headers: dict = {},
) -> None:
self.base_url: str = f"https://{BASE_API_URL}"
self.user_agent: UserAgent = user_agent
self.headers: dict = {
**{
"Host": BASE_API_URL,
"User-Agent": generate_user_agent(),
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "",
"Accept": "*/*",
"Accept-Language": "ru"
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip"
},
**headers
}
Expand Down Expand Up @@ -56,7 +52,7 @@ async def request_sms_code(self, contract: dict):

async def verify_sms_code(self, contract: dict, code: str) -> dict:
"""Verify the SMS code."""
api_url = f"{self.base_url}/auth/v2/auth/{self.phone}/confirmation"
api_url = f"{self.base_url}/auth/v3/auth/{self.phone}/confirmation"
data = json.dumps(
{
"accountId": contract["accountId"],
Expand Down Expand Up @@ -124,6 +120,7 @@ async def request(
):
"""Make a HTTP request."""
if self.access_token is not None: self.headers["Authorization"] = f"Bearer {self.access_token}"
self.headers["User-Agent"] = str(self.user_agent)

async with ClientSession() as session:
LOGGER.info("Sending API request to %s with headers=%s and data=%s", url, self.headers, data)
Expand Down
40 changes: 24 additions & 16 deletions custom_components/elektronny_gorod/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
)
from homeassistant.const import CONF_NAME
from .const import (
DOMAIN,
LOGGER,
CONF_ACCESS_TOKEN,
CONF_REFRESH_TOKEN,
CONF_PHONE,
CONF_CONTRACT,
CONF_SMS,
CONF_OPERATOR_ID,
CONF_ACCOUNT_ID,
CONF_SUBSCRIBER_ID
DOMAIN,
LOGGER,
CONF_ACCESS_TOKEN,
CONF_REFRESH_TOKEN,
CONF_PHONE,
CONF_CONTRACT,
CONF_SMS,
CONF_OPERATOR_ID,
CONF_ACCOUNT_ID,
CONF_SUBSCRIBER_ID,
USER_AGENT
)
from .api import ElektronnyGorodAPI
from .helpers import find
from .helpers import find, generate_phone
from .user_agent import UserAgent

class ElektronnyGorodConfigFlow(ConfigFlow, domain=DOMAIN):
"""Elektronny Gorod config flow."""
Expand All @@ -27,11 +29,12 @@ class ElektronnyGorodConfigFlow(ConfigFlow, domain=DOMAIN):

def __init__(self) -> None:
"""Initialize."""
self.api: ElektronnyGorodAPI = ElektronnyGorodAPI()
self.user_agent = UserAgent()
self.api: ElektronnyGorodAPI = ElektronnyGorodAPI(user_agent = self.user_agent)
self.entry: ConfigEntry | None = None
self.access_token: str | None = None
self.refresh_token: str | None = None
self.operator_id: int = 1
self.operator_id: str | int = "null"
self.phone: str | None = None
self.contract: object | None = None
self.contracts: list | None = None
Expand Down Expand Up @@ -91,7 +94,7 @@ async def async_step_contract(

# Prepare contract choices for user
contract_choices = {
str(contract["subscriberId"]): f"{contract['address']} (Account ID: {contract['accountId']})"
str(contract["subscriberId"]): f"{contract["address"]} (Account ID: {contract["accountId"]})"
for contract in self.contracts
}

Expand All @@ -105,7 +108,9 @@ async def async_step_contract(

# Request SMS code for the selected contract
try:
await self.api.request_sms_code(self.contract)
account = await self.api.request_sms_code(self.contract)
self.user_agent.place_id = account["placeId"]
self.user_agent.account_id = account["accountId"]
return await self.async_step_sms()
except:
errors[CONF_CONTRACT] = "limit_exceeded"
Expand All @@ -130,6 +135,7 @@ async def async_step_sms(
self.access_token = auth["accessToken"]
self.refresh_token = auth["refreshToken"]
self.operator_id = auth["operatorId"]
self.user_agent.operator_id = self.operator_id

# Verify the SMS code
if self.access_token:
Expand All @@ -142,6 +148,7 @@ async def async_step_sms(
CONF_ACCESS_TOKEN: self.access_token,
CONF_REFRESH_TOKEN: self.refresh_token,
CONF_OPERATOR_ID: self.operator_id,
USER_AGENT: self.user_agent,
}

for entry in self._async_current_entries():
Expand Down Expand Up @@ -173,8 +180,9 @@ async def get_account(self) -> dict:
await self.api.update_access_token(self.access_token)
profile = await self.api.query_profile()
subscriber = profile["subscriber"]
self.user_agent.account_id = subscriber["accountId"]
return {
CONF_NAME: f"{subscriber['name']} ({subscriber['accountId']})",
CONF_NAME: f"{subscriber["name"]} ({subscriber["accountId"]})",
CONF_ACCOUNT_ID: subscriber["accountId"],
CONF_SUBSCRIBER_ID: subscriber["id"]
}
95 changes: 50 additions & 45 deletions custom_components/elektronny_gorod/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Final

DOMAIN = "elektronny_gorod"
BASE_API_URL: Final = "api-mh.ertelecom.ru"
BASE_API_URL: Final = "myhome.proptech.ru"
LOGGER = logging.getLogger(__name__)

CONF_ACCESS_TOKEN: Final = "access_token"
Expand All @@ -14,52 +14,57 @@
CONF_OPERATOR_ID: Final = "operator_id"
CONF_ACCOUNT_ID: Final = "account_id"
CONF_SUBSCRIBER_ID: Final = "subscriber_id"
USER_AGENT: Final = "user_agent"

CONF_WIDTH: Final = 300
CONF_HEIGHT: Final = 300

APP_VERSION: Final = "6.16.5 (build 1)"
iOS_11: Final = ["iOS 11.0", "iOS 11.0.1", "iOS 11.0.2", "iOS 11.0.3", "iOS 11.1", "iOS 11.1.1", "iOS 11.1.2", "iOS 11.2", "iOS 11.2.1", "iOS 11.2.2", "iOS 11.2.5", "iOS 11.2.6", "iOS 11.3", "iOS 11.3.1", "iOS 11.4", "iOS 11.4.1"]
iOS_12: Final = ["iOS 12.0", "iOS 12.0.1", "iOS 12.1", "iOS 12.1.1", "iOS 12.1.2", "iOS 12.1.3", "iOS 12.1.4", "iOS 12.2", "iOS 12.3", "iOS 12.3.1", "iOS 12.3.2", "iOS 12.4", "iOS 12.4.1"]
iOS_13: Final = ["iOS 13.0", "iOS 13.1", "iOS 13.1.1", "iOS 13.1.2", "iOS 13.1.3", "iOS 13.2", "iOS 13.2.2", "iOS 13.2.3", "iOS 13.3", "iOS 13.3.1", "iOS 13.4", "iOS 13.4.1", "iOS 13.5", "iOS 13.5.1", "iOS 13.6", "iOS 13.6.1", "iOS 13.6.1", "iOS 13.7"]
iOS_14: Final = ["iOS 14.0", "iOS 14.0.1", "iOS 14.1", "iOS 14.2", "iOS 14.2.1", "iOS 14.3", "iOS 14.4", "iOS 14.4.1", "iOS 14.4.2", "iOS 14.5", "iOS 14.5.1", "iOS 14.6", "iOS 14.7", "iOS 14.7.1", "iOS 14.8", "iOS 14.8.1"]
iOS_15: Final = ["iOS 15.0", "iOS 15.0.1", "15.0.2", "iOS 15.1", "iOS 15.2", "iOS 15.2.1", "iOS 15.3", "iOS 15.3.1", "iOS 15.4", "iOS 15.4.1", "iOS 15.5", "iOS 15.6", "iOS 15.6.1", "iOS 15.7", "iOS 15.7.1", "iOS 15.7.2", "iOS 15.7.3", "iOS 15.7.4", "iOS 15.7.5", "iOS 15.7.6", "iOS 15.7.7", "iOS 15.7.8", "iOS 15.7.9", "iOS 15.8"]
iOS_16: Final = ["iOS 16.0", "iOS 16.0.1", "iOS 16.0.2", "iOS 16.0.3", "iOS 16.1", "iOS 16.1.1", "iOS 16.2", "iOS 16.3", "iOS 16.3.1", "iOS 16.4", "iOS 16.4.1", "iOS 16.5", "iOS 16.6", "iOS 16.6.1", "iOS 16.7", "iOS 16.7.1", "iOS 16.7.2", "iOS 16.7.3", "iOS 16.7.4", "iOS 16.7.5", "iOS 16.7.6", "iOS 16.7.7"]
iOS_17: Final = ["iOS 17.0", "iOS 17.0.1", "iOS 17.0.2", "iOS 17.0.3", "iOS 17.1", "iOS 17.1.1", "iOS 17.1.2", "iOS 17.2", "iOS 17.2.1", "iOS 17.3", "iOS 17.3.1", "iOS 17.4", "iOS 17.4.1"]
iPHONE_iOS_CODES: Final = [
{
"name": "iPhone 8/X",
"code": ["iPhone10,1", "iPhone10,2", "iPhone10,3", "iPhone10,4", "iPhone10,5", "iPhone10,6"],
"os": [*iOS_11, *iOS_12, *iOS_13, *iOS_14, *iOS_15, *iOS_16]
},
{
"name": "iPhone XS/XR",
"code": ["iPhone11,2", "iPhone11,4", "iPhone11,6", "iPhone11,8"],
"os": [*iOS_12, *iOS_13, *iOS_14, *iOS_15, *iOS_16, *iOS_17]
},
{
"name": "iPhone 11/SE 2",
"code": ["iPhone12,1", "iPhone12,3", "iPhone12,5", "iPhone12,8"],
"os": [*iOS_13, *iOS_14, *iOS_15, *iOS_16, *iOS_17]
},
{
"name": "iPhone 12",
"code": ["iPhone13,1", "iPhone13,2", "iPhone13,3", "iPhone13,4"],
"os": [*iOS_14, *iOS_15, *iOS_16, *iOS_17]
},
{
"name": "iPhone 13/SE 3",
"code": ["iPhone14,2", "iPhone14,3", "iPhone14,4", "iPhone14,5", "iPhone14,6"],
"os": [*iOS_15, *iOS_16, *iOS_17]
},
{
"name": "iPhone 14",
"code": ["iPhone14,7", "iPhone14,8", "iPhone15,2", "iPhone15,3"],
"os": [*iOS_16, *iOS_17]
},
{
"name": "iPhone 15",
"code": ["iPhone15,4", "iPhone15,5", "iPhone16,1", "iPhone16,2"],
"os": [*iOS_17]
},
APP_VERSION: Final = {
"name": "8.13.0",
"code": "81300000"
}

ANDROID_OS_VER: Final = "14"
ANDROID_DEVICES_CSV: Final = "https://storage.googleapis.com/play_public/supported_devices.csv"
ANDROID_DEVICES: Final = [
{
"manufacturer": "Google",
"model": "Pixel 5a",
},
{
"manufacturer": "Google",
"model": "Pixel 6",
},
{
"manufacturer": "Google",
"model": "Pixel 6 Pro",
},
{
"manufacturer": "Google",
"model": "Pixel 6a",
},
{
"manufacturer": "Google",
"model": "Pixel 7",
},
{
"manufacturer": "Google",
"model": "Pixel 7 Pro",
},
{
"manufacturer": "Google",
"model": "Pixel 7a",
},
{
"manufacturer": "Google",
"model": "Pixel 8",
},
{
"manufacturer": "Google",
"model": "Pixel 8 Pro",
},
{
"manufacturer": "Google",
"model": "Pixel 8a",
},
]
17 changes: 10 additions & 7 deletions custom_components/elektronny_gorod/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
DOMAIN,
LOGGER,
CONF_ACCESS_TOKEN,
CONF_REFRESH_TOKEN,
CONF_OPERATOR_ID,
DOMAIN,
LOGGER,
CONF_ACCESS_TOKEN,
CONF_REFRESH_TOKEN,
CONF_OPERATOR_ID,
USER_AGENT,
)
from .api import ElektronnyGorodAPI
from .helpers import find
Expand All @@ -26,12 +27,14 @@ def __init__(
"""Initialize global Elektronny Gorod data updater."""
self.access_token = entry.data[CONF_ACCESS_TOKEN]
self.refresh_token = entry.data[CONF_REFRESH_TOKEN]
self.operatorId = entry.data[CONF_OPERATOR_ID]
self.operator_id = entry.data[CONF_OPERATOR_ID]
self.user_agent = entry.data[USER_AGENT]
self.api = ElektronnyGorodAPI(
user_agent = self.user_agent,
access_token = self.access_token,
refresh_token = self.refresh_token,
headers = {
"Operator": str(self.operatorId),
"Operator": str(self.operator_id),
"Content-Type": "application/json"
}
)
Expand Down
18 changes: 0 additions & 18 deletions custom_components/elektronny_gorod/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import json
import uuid
from random import choice
from collections.abc import Callable
from .const import APP_VERSION, iPHONE_iOS_CODES

def is_json(value: str) -> bool:
try:
Expand All @@ -19,18 +16,3 @@ def find(items: list, condition: Callable) -> object:
if condition(item):
return item
return None

def generate_user_agent(
iphone: str | None = None,
ios: str | None = None,
app_ver: str = APP_VERSION,
account_id: str = "_",
operator: str = "1"
) -> str:
iphone_code = iphone
ios_code = ios
if iphone is None or ios is None:
rand_iphone = choice(iPHONE_iOS_CODES)
iphone_code = choice(rand_iphone["code"])
ios_code = choice(rand_iphone["os"])
return f"{iphone_code} | {ios_code} | ntk | {app_ver} | {account_id} | {operator} | {str(uuid.uuid4()).upper()}"
30 changes: 30 additions & 0 deletions custom_components/elektronny_gorod/user_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import uuid
from random import choice
from .const import (
APP_VERSION,
ANDROID_DEVICES,
ANDROID_OS_VER,
)

class UserAgent:
def __init__(self) -> None:
rand_phone = choice(ANDROID_DEVICES)
self.phone_manufacturer: str = rand_phone["manufacturer"]
self.phone_model: str = rand_phone["model"]
self.android_ver: str = ANDROID_OS_VER
self.app_version: dict = APP_VERSION
self.account_id: str = ""
self.operator_id: str | int = "null"
self.uuid: str = str(uuid.uuid4())
self.place_id: str = "null"

def __str__(self):
manufacturer = self.phone_manufacturer
model = self.phone_model
ver = self.android_ver
app_ver = self.app_version
account_id = self.account_id
operator_id = self.operator_id
uuid = self.uuid
place_id = self.place_id
return f"{manufacturer} {model} | Android {ver} | ntk | {app_ver["name"]} ({app_ver["code"]}) | {account_id} | {operator_id} | {uuid} | {place_id}"

0 comments on commit 1fe7a6d

Please sign in to comment.