🔍 Overview

This module provides an automated system for sending domain unblock appeals to Google Search Console using Playwright browser automation. It includes functionality for authentication, appeal submission, result tracking, and notification sending.


⚙️ Module Behavior & Flow

  1. Initialization: The AppealSenderController is initialized with a domain and its owner. It prepares to use multiple appeal senders (main and backup).
  2. Sending Appeals: The send_appeal method iterates through the list of appeal senders. For each sender:
    • It creates an instance of the sender class.
    • It calls the send method to attempt sending the appeal.
    • If the appeal is successfully sent or the domain is found to be safe, it saves the result and breaks the loop.
  3. Fallback Handling: If all senders fail to send the appeal, it logs a warning and saves the results of all attempts.
  4. Logging: Throughout the process, detailed logging is performed to track the progress and outcomes of each appeal attempt.

🛠️ Configuration

To use this module, ensure the following settings:

MAIN_APPEAL_SENDER_EMAIL = "<your_main_sender_email>"
MAIN_APPEAL_SENDER_PASSWORD = "<your_main_sender_password>"
MAIN_APPEAL_BROWSER_DATA_DIR = "<your_main_browser_data_dir>"
 
BACKUP_APPEAL_SENDER_EMAIL = "<your_backup_sender_email>"
BACKUP_APPEAL_SENDER_PASSWORD = "<your_backup_sender_password>"
BACKUP_APPEAL_BROWSER_DATA_DIR = "<your_backup_browser_data_dir>"

🧩 Browser Data

The module uses persistent browser contexts to maintain login sessions across multiple runs. Ensure that the specified BROWSER_DATA_DIR paths are writable and accessible by the application. For generating new browser data directories, you can use the following script:

import time
from playwright.sync_api import sync_playwright
 
EMAIL = "<your_email>"
PASSWORD = "<your_password>"
DOMAIN = "<your_domain>"
USER_DATA_DIR = "./browser-data-stgnashpush"
 
 
def create_browser_data():
    with sync_playwright() as p:
        browser = p.chromium.launch_persistent_context(
            user_data_dir=USER_DATA_DIR,
            headless=False,
            locale='en-US',
            args=[
                "--disable-blink-features=AutomationControlled",
                "--start-maximized",
                "--disable-dev-shm-usage",
                "--no-sandbox",
                "--use-gl=egl",
                "--disable-gpu",
                "--disable-setuid-sandbox",
                "--disable-features=IsolateOrigins,site-per-process",
                "--disable-web-security",
                "--disable-site-isolation-trials",
                "--disable-breakpad",
                "--single-process",
            ]
        )
        page = browser.new_page()
 
        try:
            # authentication
            page.goto("https://accounts.google.com/", timeout=10000)
            page.wait_for_timeout(2000)
    
            if page.url != "https://myaccount.google.com/":
                page.fill('input[type="email"]', EMAIL, timeout=5000)
                page.click('button:has-text("Next")')
                page.wait_for_selector('input[type="password"]', timeout=10000)
                page.fill('input[type="password"]', PASSWORD, timeout=5000)
                page.click('button:has-text("Next")')
                page.wait_for_timeout(2000)
 
            # go to security issues page
            security_url = f"https://search.google.com/search-console/security-issues?resource_id=sc-domain%3A{DOMAIN}"
            page.goto(security_url, timeout=12000)
 
        except Exception as e:
            print(f"❌ Error: {e}")
        finally:
            time.sleep(3)
            browser.close()
 
 
if __name__ == "__main__":
    create_browser_data()