一元网络论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 547|回复: 0

号商用来挣钱的1脚本

[复制链接]

3万

主题

3万

帖子

9万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
96256
发表于 2025-5-15 21:59:40 来自手机 | 显示全部楼层 |阅读模式
Gmi.py


import datetime
import json
import random
import string
import time

import httpx

from graph import EmailFetcher


def generate_random_string(length: int = 8) -> str:
    """Generate a random string of specified length using lowercase letters and numbers.

    Args:
        length: Length of the string to generate. Defaults to 8.

    Returns:
        str: Random string of specified length
    """
    characters = string.ascii_lowercase + string.digits
    return "".join(random.choice(characters) for _ in range(length))


def load_proxies():
    """Load and parse proxies from the proxies.txt file.

    Returns:
        list: List of proxy strings in format host:port:username:password
    """
    proxies = []
    try:
        with open("proxies.txt", "r") as f:
            for line in f:
                line = line.strip()
                if line:  # Skip empty lines
                    proxies.append(line)
        return proxies
    except Exception as e:
        print(f"Error loading proxies: {e}")
        return []


def get_random_proxy(proxies):
    """Get a random proxy from the list.

    Args:
        proxies: List of proxy strings

    Returns:
        str: A random proxy string or None if list is empty
    """
    if not proxies:
        return None
    return random.choice(proxies)


class RequestyClient:
    """Class for managing Requesty.ai account operations."""

    BASE_API_URL = "https://inference-engine.gmicloud.ai/api/v1"

    def __init__(
        self, email: str, password: str, client_id: str, refresh_token: str, proxy=None
    ):
        self.email = email
        self.password = password
        self.email_fetcher = EmailFetcher(client_id, refresh_token)
        self.client_id = client_id
        self.refresh_token = refresh_token
        self.proxy = proxy
        self.request_client_id = generate_random_string()  # 生成唯一的客户端ID

        # Setup client with or without proxy
        if proxy:
            # Format: host:port:username:password
            proxy_host, proxy_port, proxy_user, proxy_pass = proxy.split(":")
            # Construct the proxy URL in the correct format for httpx
            proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
            self.client = httpx.Client(proxy=proxy_url)
        else:
            self.client = httpx.Client()

        # 设置默认请求头
        self.client.headers.update({"ce-clientid": self.request_client_id})

        self.code = None
        self.emailVerificationToken = None
        self.authToken = None
        self.accessToken = None
        self.refreshToken = None
        self.organization_id = None

        self.balance = None
        self.apikey = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.client.close()

    def register_account(self) -> bool:
        try:
            print(f"\nUsing client ID: {self.request_client_id}")
            response = self.client.post(
                f"{self.BASE_API_URL}/users",
                json={
                    "email": self.email,
                    "password": self.password,
                    "firstName": self.email.split("@")[0],
                    "organization": {"name": self.email.split("@")[0]},
                },
            )

            if response.status_code != 201:
                print(f"Failed to get emailVerificationToken: {response.status_code}")
                print(response.text)
                return False

            response_json = response.json()
            self.emailVerificationToken = response_json["emailVerificationToken"]
            print(json.dumps(response_json, indent=4))
            return True
        except Exception as e:
            print(f"\nError during account registration: {e}")
            return False

    def retrieve_verification_code(
        self, subject="Confirm your email address", max_attempts=10
    ) -> bool:
        verification_code_pattern = r"\b(\d{6})\b"
        self.code = None

        for i in range(max_attempts):
            print(f"\nWaiting for email code... ({i + 1}/{max_attempts})")
            try:
                emails = self.email_fetcher.fetch_emails(
                    top=5, sender_filter="cluster-engine@gmicloud.ai"
                )
                if emails:
                    latest_email = emails[0]
                    print(
                        f"  Body Preview: {latest_email.get('bodyPreview', '').strip()}..."
                    )
                    if latest_email.get("subject") == subject:
                        self.code = self.email_fetcher.extract_verification_code(
                            latest_email, verification_code_pattern
                        )
                        if self.code:
                            print(f"\nVerification code: {self.code}")
                            return True
                time.sleep(3)  # Wait before checking again
            except Exception as e:
                print(f"\nError during email retrieval: {e}")
                continue

        print("Failed to retrieve verification code.")
        return False

    def verify_email(self) -> bool:
        """Verify email with the retrieved code.

        Returns:
            bool: True if verification successful, False otherwise
        """
        try:
            response = self.client.post(
                f"{self.BASE_API_URL}/users/email-verification",
                json={
                    "otpCode": self.code,
                },
                headers={
                    "Authorization": f"Bearer {self.emailVerificationToken}",
                },
            ).json()
            print(json.dumps(response, indent=4))

            # Get session ID
            if "id" in response:
                self.session_id = response["id"]
                print(f"\nSession ID: {self.session_id}")
                return True
            else:
                print(f"\nError during email verification: {response}")
                return False
        except Exception as e:
            print(f"\nError during email verification: {e}")
            return False

    def login(self) -> bool:
        self.authToken = None
        try:
            response = self.client.post(
                f"{self.BASE_API_URL}/me/auth-tokens",
                json={
                    "email": self.email,
                    "password": self.password,
                },
            ).json()
            print(json.dumps(response, indent=4))

            # Get organization ID
            self.authToken = response["authToken"]
            print(f"\nAuth Token: {self.authToken}")
            return True
        except Exception as e:
            print(f"\nError during organization creation: {e}")
            return False

    def get_access_token(self) -> bool:
        try:
            response = self.client.post(
                f"{self.BASE_API_URL}/me/sessions",
                json={
                    "authToken": self.authToken,
                    "otpCode": self.code,
                    "type": "native",
                },
            ).json()
            print(json.dumps(response, indent=4))

            self.accessToken = response["accessToken"]
            self.refreshToken = response["refreshToken"]
            print(f"\nAccess Token: {self.accessToken}")
            print(f"\nRefresh Token: {self.refreshToken}")
            return True

        except Exception as e:
            print(f"\nError during email verification: {e}")
            return False

    def get_organization(self) -> bool:
        try:
            response = self.client.get(
                f"{self.BASE_API_URL}/me/profile",
                headers={
                    "Authorization": f"Bearer {self.accessToken}",
                },
            ).json()
            print(json.dumps(response, indent=4))

            self.organization_id = response["organization"]["id"]
            print(f"\nOrganization ID: {self.organization_id}")
            return True

        except Exception as e:
            print(f"\nError during email verification: {e}")
            return False

    def redeem_promotion(self) -> bool:
        try:
            response = self.client.post(
                f"{self.BASE_API_URL}/billing/credit_coupons/INFERENCE/use",
                headers={
                    "Authorization": f"Bearer {self.accessToken}",
                },
            ).json()
            print(json.dumps(response, indent=4))
            valid = response["valid"]

            if valid:
                print(f"\nPromotion redeemed successfully: {valid}")
                return True
            else:
                print(f"\nError during promotion redemption: {response}")
                return False
        except Exception as e:
            print(f"\nError during promotion redemption: {e}")
            return False

    def get_balance(self) -> bool:
        try:
            response = self.client.get(
                f"{self.BASE_API_URL}/billing/balance",
                headers={
                    "Authorization": f"Bearer {self.accessToken}",
                },
            ).json()
            print(json.dumps(response, indent=4))

            self.balance = response["balanceAmount"]
            print(f"\nBalance: {self.balance}")
            return True

        except Exception as e:
            print(f"\nError during balance retrieval: {e}")
            return False

    def create_api_key(self) -> bool:
        try:
            response = self.client.post(
                f"{self.BASE_API_URL}/organizations/{self.organization_id}/api-keys",
                headers={
                    "Authorization": f"Bearer {self.accessToken}",
                },
                json={"name": self.email.split("@")[0], "type": "ie_model"},
            ).json()
            print(json.dumps(response, indent=4))

            self.apikey = response["key"]
            print(f"\nAPI Key: {self.apikey}")
            return True

        except Exception as e:
            print(f"\nError during API key creation: {e}")
            return False


def save_account_data(account_data: dict) -> None:
    """Save account data to a JSONL file.

    Args:
        account_data: Dictionary containing account information
    """
    try:
        # Add timestamp
        account_data["created_at"] = datetime.datetime.now().isoformat()

        # Append to JSONL file
        with open("gmi_accounts.jsonl", "a", encoding="utf-8") as f:
            f.write(json.dumps(account_data, ensure_ascii=False) + "\n")

    except Exception as e:
        print(f"\nError saving account data: {e}")


def process_account(
    email: str,
    password: str,
    client_id: str,
    refresh_token: str,
    proxy=None,
) -> bool:
    print(f"\nProcessing {email}...")
    if proxy:
        print(f"Using proxy: {proxy}")

    with RequestyClient(email, password, client_id, refresh_token, proxy) as client:
        # Step 2: Register account
        if not client.register_account():
            return False

        # Step 4: Retrieve verification code
        if not client.retrieve_verification_code():
            return False

        # Step 5: Verify email
        if not client.verify_email():
            return False

        # Step 6: Create organization
        if not client.login():
            return False

        # Step 4: Retrieve verification code
        if not client.retrieve_verification_code(
            subject="Two-Factor Authentication verification code"
        ):
            return False

        # Step 7: Get JWT token
        if not client.get_access_token():
            return False

        if not client.get_organization():
            return False

        if not client.redeem_promotion():
            return False

        # Step 8: Get account balance
        if not client.get_balance():
            return False

        # Step 9: Create API key
        if not client.create_api_key():
            return False

        # Save account data
        account_data = {
            "email": email,
            "password": password,
            "client_id": client_id,
            "refresh_token": refresh_token,
            "proxy": proxy,
            "api_key": client.apikey,
            "balance": client.balance,
            "organization_id": client.organization_id,
            "gmi_access_token": client.accessToken,
            "gmi_refresh_token": client.refreshToken,
        }
        save_account_data(account_data)

    return True


def main():
    # Load proxies
    proxies = load_proxies()

    # Process accounts from file
    with open("accounts.txt", "r") as f:
        for line in f:
            try:
                email, password, client_id, refresh_token = line.strip().split("----")
                proxy = get_random_proxy(proxies)
                process_account(email, password, client_id, refresh_token, proxy)
            except Exception as e:
                print(f"\nError processing account: {e}")


if __name__ == "__main__":
    main()


Graph.py

import httpx
import re
import time
import random


# --- Custom Exceptions ---
class EmailFetcherError(Exception):
    """Base exception for EmailFetcher errors."""

    pass


class TokenError(EmailFetcherError):
    """Raised when there's an error obtaining the access token."""

    pass


class GraphApiError(EmailFetcherError):
    """Raised when there's an error during a Microsoft Graph API call."""

    pass


class InvalidRegexError(EmailFetcherError):
    """Raised when the provided regex pattern is invalid."""

    pass


# --- End Custom Exceptions ---


class EmailFetcher:
    BASE_URL = "https://graph.microsoft.com/v1.0"
    TOKEN_URL = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"
    MAX_RETRIES = 3  # Maximum number of retry attempts
    BASE_RETRY_DELAY = 2  # Base delay in seconds

    def __init__(self, client_id, refresh_token):
        self.client_id = client_id
        self.refresh_token = refresh_token
        self.access_token = None

    def _get_access_token(self):
        """Retrieves or refreshes the access token. Raises TokenError on failure."""
        data = {
            "client_id": self.client_id,
            "grant_type": "refresh_token",
            "refresh_token": self.refresh_token,
            "scope": "https://graph.microsoft.com/.default",
        }
        
        retries = 0
        while retries <= self.MAX_RETRIES:
            try:
                response = httpx.post(self.TOKEN_URL, data=data)
               
                # Handle 429 Too Many Requests specifically
                if response.status_code == 429:
                    if retries == self.MAX_RETRIES:
                        error_msg = f"Token request failed after {self.MAX_RETRIES} retries due to rate limiting (429)"
                        print(error_msg)
                        raise TokenError(error_msg)
                    
                    # Get retry-after header if available, otherwise use exponential backoff
                    retry_after = response.headers.get('Retry-After')
                    if retry_after and retry_after.isdigit():
                        delay = int(retry_after)
                    else:
                        # Exponential backoff with jitter
                        delay = self.BASE_RETRY_DELAY * (2 ** retries) + random.uniform(0, 1)
                    
                    print(f"Rate limited (429). Retrying in {delay:.2f} seconds... (Attempt {retries+1}/{self.MAX_RETRIES})")
                    time.sleep(delay)
                    retries += 1
                    continue
               
                response.raise_for_status()  # Raise an exception for other bad status codes
                result = response.json()

                if "error" in result:
                    error_msg = f"Access token error: {result.get('error')}, Description: {result.get('error_description')}"
                    print(error_msg)  # Also print for immediate feedback
                    raise TokenError(error_msg)

                self.access_token = result.get("access_token")
                if not self.access_token:
                    raise TokenError("No access token found in the response.")
                return self.access_token
               
            except httpx.HTTPStatusError as e:
                # For other HTTP errors that aren't 429
                if e.response.status_code != 429:
                    error_msg = f"Token request failed with status {e.response.status_code}: {e.response.text}"
                    print(error_msg)
                    raise TokenError(error_msg) from e
                # 429 errors are handled in the code above
               
            except httpx.RequestError as e:
                error_msg = f"Token request network error: {e}"
                print(error_msg)
                raise TokenError(error_msg) from e
               
            except Exception as e:
                if isinstance(e, TokenError):
                    raise  # Re-raise TokenError without wrapping
                error_msg = f"An unexpected error occurred during token request: {e}"
                print(error_msg)
                raise TokenError(error_msg) from e

    def fetch_emails(self, top=50, sender_filter=None):
        """
        Fetches emails and performs client-side filtering.
        Raises TokenError or GraphApiError on failure.

        Args:
            top: Maximum number of emails to fetch
            sender_filter: Optional email address to filter by (client-side filtering)

        Returns:
            List of filtered email objects
        """
        try:
            if not self.access_token:
                # Attempt to get token, will raise TokenError if it fails
                self._get_access_token()
        except TokenError as e:
            # Re-raise token errors so the caller knows token fetch failed
            raise GraphApiError(
                "Failed to obtain access token before fetching emails."
            ) from e

        # Construct the base URL
        url = f"{self.BASE_URL}/me/messages"

        # Prepare query parameters - only use ordering and top, no server-side filtering
        params = {"$orderby": "receivedDateTime desc", "$top": top}

        headers = {"Authorization": f"Bearer {self.access_token}"}

        retries = 0
        while retries <= self.MAX_RETRIES:
            try:
                response = httpx.get(url, headers=headers, params=params)
               
                # Handle 429 Too Many Requests specifically
                if response.status_code == 429:
                    if retries == self.MAX_RETRIES:
                        error_msg = f"Graph API request failed after {self.MAX_RETRIES} retries due to rate limiting (429)"
                        print(error_msg)
                        raise GraphApiError(error_msg)
                    
                    # Get retry-after header if available, otherwise use exponential backoff
                    retry_after = response.headers.get('Retry-After')
                    if retry_after and retry_after.isdigit():
                        delay = int(retry_after)
                    else:
                        # Exponential backoff with jitter
                        delay = self.BASE_RETRY_DELAY * (2 ** retries) + random.uniform(0, 1)
                    
                    print(f"Rate limited (429). Retrying in {delay:.2f} seconds... (Attempt {retries+1}/{self.MAX_RETRIES})")
                    time.sleep(delay)
                    retries += 1
                    continue
               
                response.raise_for_status()  # Check for other HTTP errors
                all_emails = response.json().get("value", [])

                # Perform client-side filtering if a sender filter is specified
                if sender_filter and all_emails:
                    filtered_emails = []
                    for email in all_emails:
                        sender_address = (
                            email.get("from", {}).get("emailAddress", {}).get("address", "")
                        )
                        if (
                            sender_address
                            and sender_filter.lower() in sender_address.lower()
                        ):
                            filtered_emails.append(email)
                    return filtered_emails

                # Return all emails if no filter is specified
                return all_emails

            except httpx.HTTPStatusError as e:
                # For other HTTP errors that aren't 429
                if e.response.status_code != 429:
                    error_msg = f"Graph API request failed with status {e.response.status_code}: {e.response.text}"
                    print(error_msg)
                    # Handle specific errors like token expiry if needed
                    if e.response.status_code == 401:  # Unauthorized - token might have expired
                        print(
                            "Access token might be invalid or expired. Clearing token for retry."
                        )
                        self.access_token = None  # Clear token
                    raise GraphApiError(error_msg) from e
                # 429 errors are handled in the code above
               
            except httpx.RequestError as e:
                error_msg = f"Graph API request network error: {e}"
                print(error_msg)
                raise GraphApiError(error_msg) from e
               
            except Exception as e:
                error_msg = f"An unexpected error occurred during Graph API request: {e}"
                print(error_msg)
                raise GraphApiError(error_msg) from e

    def extract_verification_code(self, email, pattern):
        """Extracts code using regex. Raises InvalidRegexError or returns None."""
        if not email or not isinstance(email, dict):
            return None

        subject = email.get("subject", "")
        body_preview = email.get("bodyPreview", "")
        body_content = email.get("body", {}).get("content", "")

        try:
            regex = re.compile(pattern)
        except re.error as e:
            error_msg = f"Invalid regex pattern '{pattern}': {e}"
            print(error_msg)
            raise InvalidRegexError(error_msg) from e

        # Search order: subject, body preview, full body
        for text_source in [subject, body_preview, body_content]:
            if text_source:  # Ensure source is not None or empty
                match = regex.search(text_source)
                if match:
                    # Assuming the code is in the first capture group
                    # If pattern has no groups, match.group(0) is the whole match
                    return match.group(1) if regex.groups >= 1 else match.group(0)

        return None  # No code found




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|一元网络论坛

GMT+8, 2025-6-7 23:26 , Processed in 0.117509 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表