Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# PocketOption Tools

This directory contains utility tools for working with the PocketOption API.

## get_ssid.py - SSID Extraction Tool

This tool automatically extracts your PocketOption session ID (SSID) by monitoring WebSocket traffic during login.

### What is SSID?

SSID (Session ID) is the authentication token required to use the PocketOption API. It's a string that looks like:

```
42["auth",{"session":"your-session-here","isDemo":1,"uid":12345,"platform":1}]
```

### Prerequisites

Before running the tool, make sure you have the required dependencies installed:

```bash
pip install -r requirements.txt
```

The tool requires:
- `selenium>=4.0.0`
- `webdriver-manager>=4.0.0`
- Chrome browser installed on your system

### How to Use

1. **Navigate to the tools directory:**
```bash
cd tools
```

2. **Run the script:**
```bash
python get_ssid.py
```

3. **Follow the on-screen instructions:**
- A Chrome browser window will open automatically
- Navigate to the PocketOption login page
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an inconsistency in the instructions. Step 3 says "Navigate to the PocketOption login page" but the script automatically navigates to the login page (line 95 in the code: driver.get(login_url)). The instruction should say "The browser will automatically navigate to the PocketOption login page" or similar to reflect the actual behavior.

Suggested change
- Navigate to the PocketOption login page
- The browser will automatically navigate to the PocketOption login page

Copilot uses AI. Check for mistakes.
- Log in with your credentials
- Wait for the automatic redirection to the trading cabinet
- The script will automatically extract and save your SSID

4. **Find your SSID:**
- The SSID will be saved to a `.env` file in the current directory
- You can now use this SSID in your API scripts

### Expected Output

When successful, you'll see:

```
2025-12-25 10:30:15 - INFO - ================================================================================
2025-12-25 10:30:15 - INFO - PocketOption SSID Extractor Tool
2025-12-25 10:30:15 - INFO - ================================================================================
2025-12-25 10:30:15 - INFO - INSTRUCTIONS:
2025-12-25 10:30:15 - INFO - 1. A Chrome browser will open shortly
2025-12-25 10:30:15 - INFO - 2. Please log in to PocketOption with your credentials
...
2025-12-25 10:31:45 - INFO - Found valid SSID string in WebSocket payload
2025-12-25 10:31:45 - INFO - ================================================================================
2025-12-25 10:31:45 - INFO - SUCCESS! SSID successfully extracted and saved to .env file.
2025-12-25 10:31:45 - INFO - You can now use this SSID in your PocketOption API scripts.
2025-12-25 10:31:45 - INFO - ================================================================================
Comment on lines +58 to +69
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example output uses the date "2025-12-25" which is today's date. For documentation examples showing sample output, it's better to use placeholder dates or dates clearly in the past to avoid confusion. Consider using a placeholder like "YYYY-MM-DD" or a generic past date.

Suggested change
2025-12-25 10:30:15 - INFO - ================================================================================
2025-12-25 10:30:15 - INFO - PocketOption SSID Extractor Tool
2025-12-25 10:30:15 - INFO - ================================================================================
2025-12-25 10:30:15 - INFO - INSTRUCTIONS:
2025-12-25 10:30:15 - INFO - 1. A Chrome browser will open shortly
2025-12-25 10:30:15 - INFO - 2. Please log in to PocketOption with your credentials
...
2025-12-25 10:31:45 - INFO - Found valid SSID string in WebSocket payload
2025-12-25 10:31:45 - INFO - ================================================================================
2025-12-25 10:31:45 - INFO - SUCCESS! SSID successfully extracted and saved to .env file.
2025-12-25 10:31:45 - INFO - You can now use this SSID in your PocketOption API scripts.
2025-12-25 10:31:45 - INFO - ================================================================================
YYYY-MM-DD HH:MM:SS - INFO - ================================================================================
YYYY-MM-DD HH:MM:SS - INFO - PocketOption SSID Extractor Tool
YYYY-MM-DD HH:MM:SS - INFO - ================================================================================
YYYY-MM-DD HH:MM:SS - INFO - INSTRUCTIONS:
YYYY-MM-DD HH:MM:SS - INFO - 1. A Chrome browser will open shortly
YYYY-MM-DD HH:MM:SS - INFO - 2. Please log in to PocketOption with your credentials
...
YYYY-MM-DD HH:MM:SS - INFO - Found valid SSID string in WebSocket payload
YYYY-MM-DD HH:MM:SS - INFO - ================================================================================
YYYY-MM-DD HH:MM:SS - INFO - SUCCESS! SSID successfully extracted and saved to .env file.
YYYY-MM-DD HH:MM:SS - INFO - You can now use this SSID in your PocketOption API scripts.
YYYY-MM-DD HH:MM:SS - INFO - ================================================================================

Copilot uses AI. Check for mistakes.
```

### Troubleshooting

#### "SSID string pattern not found in WebSocket logs"

If you see this warning, try the following:

1. **Run the script again** - Sometimes the WebSocket connection timing can vary
2. **Manual extraction method:**
- Open PocketOption in Chrome
- Press F12 to open Developer Tools
- Go to the "Network" tab
- Filter by "WS" (WebSocket)
- Log in and navigate to a trading page
- Look for messages containing `42["auth"`
- Copy the complete message including the `42["auth",{...}]` format
- Save it to your `.env` file as: `SSID="your-copied-message"`

#### Browser doesn't open

- Make sure Chrome is installed on your system
- The script uses `webdriver-manager` which automatically downloads ChromeDriver
- Check your internet connection

#### Other issues

- Make sure all dependencies are installed: `pip install -r requirements.txt`
- Check the console output for specific error messages
- Try running the script with Python 3.8 or higher

### Using Your SSID

Once you have your SSID, you can use it in your API scripts:

```python
from pocketoptionapi_async import AsyncPocketOptionClient
import asyncio

async def main():
# Load SSID from environment or paste it directly
SSID = "42[\"auth\",{\"session\":\"...\",\"isDemo\":1,\"uid\":12345,\"platform\":1}]"

client = AsyncPocketOptionClient(SSID, is_demo=True)
await client.connect()

balance = await client.get_balance()
print(f"Balance: {balance.balance} {balance.currency}")

await client.disconnect()

asyncio.run(main())
```

### Security Note

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.
127 changes: 97 additions & 30 deletions tools/get_ssid.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
from driver import get_driver

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

Expand Down Expand Up @@ -57,26 +57,47 @@ def get_pocketoption_ssid():
Automates the process of logging into PocketOption, navigating to a specific cabinet page,
and then scraping WebSocket traffic to extract the session ID (SSID).
The extracted SSID is then saved to the .env file.

Instructions:
1. Run this script
2. A Chrome browser will open and navigate to PocketOption login page
3. Log in manually with your credentials
4. Wait for the script to automatically extract your SSID
5. The SSID will be saved to .env file in the current directory
"""
driver = None
try:
logger.info("=" * 80)
logger.info("PocketOption SSID Extractor Tool")
logger.info("=" * 80)
logger.info("INSTRUCTIONS:")
logger.info("1. A Chrome browser will open shortly")
logger.info("2. Please log in to PocketOption with your credentials")
logger.info("3. Wait for automatic redirection to the trading cabinet")
logger.info("4. The script will extract your SSID automatically")
logger.info("=" * 80)

# Initialize the Selenium WebDriver using the helper function from driver.py.
# This ensures the browser profile is persistent for easier logins.
driver = get_driver("chrome")
login_url = "https://pocketoption.com/en/login"
cabinet_base_url = "https://pocketoption.com/en/cabinet"
target_cabinet_url = "https://pocketoption.com/en/cabinet/demo-quick-high-low/"
# Regex to capture the entire "42[\"auth\",{...}]" string.
# This pattern is designed to be robust and capture the full authentication message,
# regardless of the specific content of the 'session' field (e.g., simple string or serialized PHP array).
ssid_pattern = r'(42\["auth",\{"session":"[^"]+","isDemo":\d+,"uid":\d+,"platform":\d+,"isFastHistory":(?:true|false)\}\])'

# Flexible regex pattern to capture auth messages in various formats
# This pattern handles:
# - Optional isFastHistory field
# - Any field order in the JSON object
# - Various session string formats
ssid_pattern = r'42\["auth",(\{(?:[^{}]|\{[^}]*\})*\})\]'
Comment on lines +88 to +92
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern r'42\["auth",(\{(?:[^{}]|\{[^}]*\})*\})\]' only handles one level of nested braces within the JSON object. If the session field or any other field contains a JSON object with nested braces beyond one level, this pattern will fail to match correctly. Consider using a more robust JSON parsing approach or a recursive pattern if nested objects are possible in the auth message.

Suggested change
# This pattern handles:
# - Optional isFastHistory field
# - Any field order in the JSON object
# - Various session string formats
ssid_pattern = r'42\["auth",(\{(?:[^{}]|\{[^}]*\})*\})\]'
# This pattern now captures the entire JSON payload after 42["auth",
# and relies on json.loads to correctly parse any nested objects.
# It matches messages of the form: 42["auth",<json>]
ssid_pattern = r'42\["auth",(.*)\]'

Copilot uses AI. Check for mistakes.

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

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

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

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

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

found_full_ssid_string = None
websocket_frames_found = 0
auth_messages_found = 0

# Iterate through the performance logs to find WebSocket frames.
for entry in performance_logs:
message = json.loads(entry["message"])
# Check if the log entry is a WebSocket frame (either sent or received)
# and contains the desired payload data.
if (
message["message"]["method"] == "Network.webSocketFrameReceived"
or message["message"]["method"] == "Network.webSocketFrameSent"
):
payload_data = message["message"]["params"]["response"]["payloadData"]
# Attempt to find the full SSID string using the defined regex pattern.
match = re.search(ssid_pattern, payload_data)
if match:
# Capture the entire matched group as the full SSID string.
found_full_ssid_string = match.group(1)
logger.info(
f"Found full SSID string in WebSocket payload: {found_full_ssid_string}"
)
# Break after finding the first match as it's likely the correct one.
break
try:
message = json.loads(entry["message"])
# Check if the log entry is a WebSocket frame (either sent or received)
# and contains the desired payload data.
if (
message["message"]["method"] == "Network.webSocketFrameReceived"
or message["message"]["method"] == "Network.webSocketFrameSent"
):
websocket_frames_found += 1
payload_data = message["message"]["params"]["response"]["payloadData"]

# Check if this is an auth-related message
if '"auth"' in payload_data:
auth_messages_found += 1
logger.debug(f"Found auth message: {payload_data[:200]}...")
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logging level is set to INFO (line 14), but this code uses logger.debug() at lines 148 and 174. These debug messages will never be displayed to users. Either change these to logger.info() if the information is useful for users, or consider making the logging level configurable if you want to support debug output.

Copilot uses AI. Check for mistakes.

# Attempt to find the full SSID string using the defined regex pattern.
match = re.search(ssid_pattern, payload_data)
if match:
# Reconstruct the full SSID string
json_part = match.group(1)
found_full_ssid_string = f'42["auth",{json_part}]'

# Validate that it contains required fields
try:
data = json.loads(json_part)
if "session" in data and "uid" in data:
logger.info(
f"Found valid SSID string in WebSocket payload"
)
logger.info(f"SSID preview: 42[\"auth\",{{\"session\":\"***\",\"uid\":{data.get('uid')},\"isDemo\":{data.get('isDemo', 'N/A')},...}}]")
# Break after finding the first valid match
break
else:
logger.warning(f"Found auth message but missing required fields: {list(data.keys())}")
found_full_ssid_string = None
except json.JSONDecodeError as e:
logger.warning(f"Found auth pattern but invalid JSON: {e}")
found_full_ssid_string = None
except Exception as e:
logger.debug(f"Error processing log entry: {e}")
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logging level is set to INFO (line 14), but this code uses logger.debug(). This debug message will never be displayed to users. Either change this to logger.info() if the information is useful, or consider making the logging level configurable.

Suggested change
logger.debug(f"Error processing log entry: {e}")
logger.info(f"Error processing log entry: {e}")

Copilot uses AI. Check for mistakes.
continue

logger.info(f"Statistics: Found {websocket_frames_found} WebSocket frames, {auth_messages_found} auth messages")

if found_full_ssid_string:
# Save the extracted full SSID string to the .env file.
save_to_env("SSID", found_full_ssid_string)
logger.info("Full SSID string successfully extracted and saved to .env.")
logger.info("=" * 80)
logger.info("SUCCESS! SSID successfully extracted and saved to .env file.")
logger.info("You can now use this SSID in your PocketOption API scripts.")
logger.info("=" * 80)
else:
logger.warning("=" * 80)
logger.warning(
"Full SSID string pattern not found in WebSocket logs after login."
"SSID string pattern not found in WebSocket logs after login."
)
logger.warning("Possible reasons:")
logger.warning("1. WebSocket connection was not established yet (try running again)")
logger.warning("2. You may need to navigate to a trading page manually")
logger.warning("3. The auth message format has changed")
logger.warning("")
logger.warning("Alternative method to get SSID:")
logger.warning("1. Open PocketOption in Chrome")
logger.warning("2. Open Developer Tools (F12)")
logger.warning("3. Go to Network tab and filter by 'WS' (WebSocket)")
logger.warning("4. Look for messages containing '42[\"auth\"'")
logger.warning("5. Copy the complete message including the 42[\"auth\",{...}] format")
logger.warning("=" * 80)

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