Skip to content

Commit 98cf033

Browse files
authored
Merge pull request #57 from ChipaDevTeam/copilot/update-get-ssid-script
[WIP] Update get_ssid.py script for improved SSID retrieval
2 parents 10a6911 + 2326aab commit 98cf033

File tree

2 files changed

+223
-30
lines changed

2 files changed

+223
-30
lines changed

tools/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# PocketOption Tools
2+
3+
This directory contains utility tools for working with the PocketOption API.
4+
5+
## get_ssid.py - SSID Extraction Tool
6+
7+
This tool automatically extracts your PocketOption session ID (SSID) by monitoring WebSocket traffic during login.
8+
9+
### What is SSID?
10+
11+
SSID (Session ID) is the authentication token required to use the PocketOption API. It's a string that looks like:
12+
13+
```
14+
42["auth",{"session":"your-session-here","isDemo":1,"uid":12345,"platform":1}]
15+
```
16+
17+
### Prerequisites
18+
19+
Before running the tool, make sure you have the required dependencies installed:
20+
21+
```bash
22+
pip install -r requirements.txt
23+
```
24+
25+
The tool requires:
26+
- `selenium>=4.0.0`
27+
- `webdriver-manager>=4.0.0`
28+
- Chrome browser installed on your system
29+
30+
### How to Use
31+
32+
1. **Navigate to the tools directory:**
33+
```bash
34+
cd tools
35+
```
36+
37+
2. **Run the script:**
38+
```bash
39+
python get_ssid.py
40+
```
41+
42+
3. **Follow the on-screen instructions:**
43+
- A Chrome browser window will open automatically
44+
- Navigate to the PocketOption login page
45+
- Log in with your credentials
46+
- Wait for the automatic redirection to the trading cabinet
47+
- The script will automatically extract and save your SSID
48+
49+
4. **Find your SSID:**
50+
- The SSID will be saved to a `.env` file in the current directory
51+
- You can now use this SSID in your API scripts
52+
53+
### Expected Output
54+
55+
When successful, you'll see:
56+
57+
```
58+
2025-12-25 10:30:15 - INFO - ================================================================================
59+
2025-12-25 10:30:15 - INFO - PocketOption SSID Extractor Tool
60+
2025-12-25 10:30:15 - INFO - ================================================================================
61+
2025-12-25 10:30:15 - INFO - INSTRUCTIONS:
62+
2025-12-25 10:30:15 - INFO - 1. A Chrome browser will open shortly
63+
2025-12-25 10:30:15 - INFO - 2. Please log in to PocketOption with your credentials
64+
...
65+
2025-12-25 10:31:45 - INFO - Found valid SSID string in WebSocket payload
66+
2025-12-25 10:31:45 - INFO - ================================================================================
67+
2025-12-25 10:31:45 - INFO - SUCCESS! SSID successfully extracted and saved to .env file.
68+
2025-12-25 10:31:45 - INFO - You can now use this SSID in your PocketOption API scripts.
69+
2025-12-25 10:31:45 - INFO - ================================================================================
70+
```
71+
72+
### Troubleshooting
73+
74+
#### "SSID string pattern not found in WebSocket logs"
75+
76+
If you see this warning, try the following:
77+
78+
1. **Run the script again** - Sometimes the WebSocket connection timing can vary
79+
2. **Manual extraction method:**
80+
- Open PocketOption in Chrome
81+
- Press F12 to open Developer Tools
82+
- Go to the "Network" tab
83+
- Filter by "WS" (WebSocket)
84+
- Log in and navigate to a trading page
85+
- Look for messages containing `42["auth"`
86+
- Copy the complete message including the `42["auth",{...}]` format
87+
- Save it to your `.env` file as: `SSID="your-copied-message"`
88+
89+
#### Browser doesn't open
90+
91+
- Make sure Chrome is installed on your system
92+
- The script uses `webdriver-manager` which automatically downloads ChromeDriver
93+
- Check your internet connection
94+
95+
#### Other issues
96+
97+
- Make sure all dependencies are installed: `pip install -r requirements.txt`
98+
- Check the console output for specific error messages
99+
- Try running the script with Python 3.8 or higher
100+
101+
### Using Your SSID
102+
103+
Once you have your SSID, you can use it in your API scripts:
104+
105+
```python
106+
from pocketoptionapi_async import AsyncPocketOptionClient
107+
import asyncio
108+
109+
async def main():
110+
# Load SSID from environment or paste it directly
111+
SSID = "42[\"auth\",{\"session\":\"...\",\"isDemo\":1,\"uid\":12345,\"platform\":1}]"
112+
113+
client = AsyncPocketOptionClient(SSID, is_demo=True)
114+
await client.connect()
115+
116+
balance = await client.get_balance()
117+
print(f"Balance: {balance.balance} {balance.currency}")
118+
119+
await client.disconnect()
120+
121+
asyncio.run(main())
122+
```
123+
124+
### Security Note
125+
126+
Your SSID is sensitive information that grants access to your PocketOption account. Keep it secure and never share it publicly. The `.env` file should be added to `.gitignore` to prevent accidental commits.

tools/get_ssid.py

Lines changed: 97 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from driver import get_driver
1010

1111
# Configure logging for this script to provide clear, structured output.
12-
# Logs will be directed to standard output, making them compatible with containerization
13-
# and centralized log collection systems.
12+
# Using a simpler format for better readability by end users.
1413
logging.basicConfig(
1514
level=logging.INFO,
16-
format='{"timestamp": "%(asctime)s", "level": "%(levelname)s", "module": "%(name)s", "message": "%(message)s"}',
15+
format='%(asctime)s - %(levelname)s - %(message)s',
16+
datefmt='%Y-%m-%d %H:%M:%S'
1717
)
1818
logger = logging.getLogger(__name__)
1919

@@ -57,26 +57,47 @@ def get_pocketoption_ssid():
5757
Automates the process of logging into PocketOption, navigating to a specific cabinet page,
5858
and then scraping WebSocket traffic to extract the session ID (SSID).
5959
The extracted SSID is then saved to the .env file.
60+
61+
Instructions:
62+
1. Run this script
63+
2. A Chrome browser will open and navigate to PocketOption login page
64+
3. Log in manually with your credentials
65+
4. Wait for the script to automatically extract your SSID
66+
5. The SSID will be saved to .env file in the current directory
6067
"""
6168
driver = None
6269
try:
70+
logger.info("=" * 80)
71+
logger.info("PocketOption SSID Extractor Tool")
72+
logger.info("=" * 80)
73+
logger.info("INSTRUCTIONS:")
74+
logger.info("1. A Chrome browser will open shortly")
75+
logger.info("2. Please log in to PocketOption with your credentials")
76+
logger.info("3. Wait for automatic redirection to the trading cabinet")
77+
logger.info("4. The script will extract your SSID automatically")
78+
logger.info("=" * 80)
79+
6380
# Initialize the Selenium WebDriver using the helper function from driver.py.
6481
# This ensures the browser profile is persistent for easier logins.
6582
driver = get_driver("chrome")
6683
login_url = "https://pocketoption.com/en/login"
6784
cabinet_base_url = "https://pocketoption.com/en/cabinet"
6885
target_cabinet_url = "https://pocketoption.com/en/cabinet/demo-quick-high-low/"
69-
# Regex to capture the entire "42[\"auth\",{...}]" string.
70-
# This pattern is designed to be robust and capture the full authentication message,
71-
# regardless of the specific content of the 'session' field (e.g., simple string or serialized PHP array).
72-
ssid_pattern = r'(42\["auth",\{"session":"[^"]+","isDemo":\d+,"uid":\d+,"platform":\d+,"isFastHistory":(?:true|false)\}\])'
86+
87+
# Flexible regex pattern to capture auth messages in various formats
88+
# This pattern handles:
89+
# - Optional isFastHistory field
90+
# - Any field order in the JSON object
91+
# - Various session string formats
92+
ssid_pattern = r'42\["auth",(\{(?:[^{}]|\{[^}]*\})*\})\]'
7393

7494
logger.info(f"Navigating to login page: {login_url}")
7595
driver.get(login_url)
7696

7797
# Wait indefinitely for the user to manually log in and be redirected to the cabinet base page.
7898
# This uses an explicit wait condition to check if the current URL contains the cabinet_base_url.
7999
logger.info(f"Waiting for user to login and redirect to {cabinet_base_url}...")
100+
logger.info("Please complete the login in the browser window...")
80101
WebDriverWait(driver, 9999).until(EC.url_contains(cabinet_base_url))
81102
logger.info("Login successful. Redirected to cabinet base page.")
82103

@@ -89,9 +110,10 @@ def get_pocketoption_ssid():
89110
WebDriverWait(driver, 60).until(EC.url_contains(target_cabinet_url))
90111
logger.info("Successfully navigated to the target cabinet page.")
91112

92-
# Give the page some time to load all WebSocket connections and messages after redirection.
93-
# This delay helps ensure that the relevant WebSocket frames are captured in the logs.
94-
time.sleep(5)
113+
# Give the page more time to establish WebSocket connections and capture auth messages
114+
# Increased from 5 to 10 seconds to ensure auth messages are captured
115+
logger.info("Waiting for WebSocket connections to establish...")
116+
time.sleep(10)
95117

96118
# Retrieve performance logs which include network requests and WebSocket frames.
97119
# These logs are crucial for capturing the raw WebSocket messages.
@@ -104,35 +126,80 @@ def get_pocketoption_ssid():
104126
logger.info(f"Collected {len(performance_logs)} performance log entries.")
105127

106128
found_full_ssid_string = None
129+
websocket_frames_found = 0
130+
auth_messages_found = 0
131+
107132
# Iterate through the performance logs to find WebSocket frames.
108133
for entry in performance_logs:
109-
message = json.loads(entry["message"])
110-
# Check if the log entry is a WebSocket frame (either sent or received)
111-
# and contains the desired payload data.
112-
if (
113-
message["message"]["method"] == "Network.webSocketFrameReceived"
114-
or message["message"]["method"] == "Network.webSocketFrameSent"
115-
):
116-
payload_data = message["message"]["params"]["response"]["payloadData"]
117-
# Attempt to find the full SSID string using the defined regex pattern.
118-
match = re.search(ssid_pattern, payload_data)
119-
if match:
120-
# Capture the entire matched group as the full SSID string.
121-
found_full_ssid_string = match.group(1)
122-
logger.info(
123-
f"Found full SSID string in WebSocket payload: {found_full_ssid_string}"
124-
)
125-
# Break after finding the first match as it's likely the correct one.
126-
break
134+
try:
135+
message = json.loads(entry["message"])
136+
# Check if the log entry is a WebSocket frame (either sent or received)
137+
# and contains the desired payload data.
138+
if (
139+
message["message"]["method"] == "Network.webSocketFrameReceived"
140+
or message["message"]["method"] == "Network.webSocketFrameSent"
141+
):
142+
websocket_frames_found += 1
143+
payload_data = message["message"]["params"]["response"]["payloadData"]
144+
145+
# Check if this is an auth-related message
146+
if '"auth"' in payload_data:
147+
auth_messages_found += 1
148+
logger.debug(f"Found auth message: {payload_data[:200]}...")
149+
150+
# Attempt to find the full SSID string using the defined regex pattern.
151+
match = re.search(ssid_pattern, payload_data)
152+
if match:
153+
# Reconstruct the full SSID string
154+
json_part = match.group(1)
155+
found_full_ssid_string = f'42["auth",{json_part}]'
156+
157+
# Validate that it contains required fields
158+
try:
159+
data = json.loads(json_part)
160+
if "session" in data and "uid" in data:
161+
logger.info(
162+
f"Found valid SSID string in WebSocket payload"
163+
)
164+
logger.info(f"SSID preview: 42[\"auth\",{{\"session\":\"***\",\"uid\":{data.get('uid')},\"isDemo\":{data.get('isDemo', 'N/A')},...}}]")
165+
# Break after finding the first valid match
166+
break
167+
else:
168+
logger.warning(f"Found auth message but missing required fields: {list(data.keys())}")
169+
found_full_ssid_string = None
170+
except json.JSONDecodeError as e:
171+
logger.warning(f"Found auth pattern but invalid JSON: {e}")
172+
found_full_ssid_string = None
173+
except Exception as e:
174+
logger.debug(f"Error processing log entry: {e}")
175+
continue
176+
177+
logger.info(f"Statistics: Found {websocket_frames_found} WebSocket frames, {auth_messages_found} auth messages")
127178

128179
if found_full_ssid_string:
129180
# Save the extracted full SSID string to the .env file.
130181
save_to_env("SSID", found_full_ssid_string)
131-
logger.info("Full SSID string successfully extracted and saved to .env.")
182+
logger.info("=" * 80)
183+
logger.info("SUCCESS! SSID successfully extracted and saved to .env file.")
184+
logger.info("You can now use this SSID in your PocketOption API scripts.")
185+
logger.info("=" * 80)
132186
else:
187+
logger.warning("=" * 80)
133188
logger.warning(
134-
"Full SSID string pattern not found in WebSocket logs after login."
189+
"SSID string pattern not found in WebSocket logs after login."
135190
)
191+
logger.warning("Possible reasons:")
192+
logger.warning("1. WebSocket connection was not established yet (try running again)")
193+
logger.warning("2. You may need to navigate to a trading page manually")
194+
logger.warning("3. The auth message format has changed")
195+
logger.warning("")
196+
logger.warning("Alternative method to get SSID:")
197+
logger.warning("1. Open PocketOption in Chrome")
198+
logger.warning("2. Open Developer Tools (F12)")
199+
logger.warning("3. Go to Network tab and filter by 'WS' (WebSocket)")
200+
logger.warning("4. Look for messages containing '42[\"auth\"'")
201+
logger.warning("5. Copy the complete message including the 42[\"auth\",{...}] format")
202+
logger.warning("=" * 80)
136203

137204
except Exception as e:
138205
logger.error(f"An error occurred: {e}", exc_info=True)

0 commit comments

Comments
 (0)