بازگشت به وبلاگ

چگونه از طریق API آمار استفاده از پروکسی را دریافت کنیم: اتوماسیون حسابرسی ترافیک

راهنمای جامع کار با API ارائه‌دهندگان پروکسی برای دریافت آمار استفاده: نمونه‌های کد، روش‌های اتوماسیون و ادغام در فرآیندهای کسب‌وکار

📅۲۷ بهمن ۱۴۰۴
```html

اگر شما با تعداد زیادی پروکسی کار می‌کنید — برای آربیتراژ، پارسینگ یا چند حساب کاربری — کنترل دستی مصرف ترافیک به یک کابوس تبدیل می‌شود. API ارائه‌دهندگان پروکسی امکان اتوماسیون دریافت آمار را فراهم می‌کند: موجودی ترافیک، جلسات فعال، مصرف بر اساس آدرس‌های IP و تاریخچه استفاده. در این راهنما، نحوه ادغام API برای حسابرسی آمار را با مثال‌های کد در Python، Node.js و cURL بررسی خواهیم کرد.

چرا اتوماسیون آمار پروکسی ضروری است

زمانی که شما 10-50 پروکسی را برای پروژه‌های مختلف مدیریت می‌کنید، بررسی دستی موجودی و مصرف ترافیک از طریق پنل کاربری ارائه‌دهنده غیر مؤثر می‌شود. API چندین وظیفه بحرانی را حل می‌کند:

وظایف اصلی API آمار:

  • نظارت بر موجودی ترافیک — اعلان‌های خودکار هنگام رسیدن به حد مجاز
  • کنترل مصرف بر اساس پروژه‌ها — توزیع هزینه‌ها بین مشتریان یا وظایف
  • تحلیل کارایی — کدام پروکسی‌ها بیشتر ترافیک مصرف می‌کنند و چرا
  • پیشگیری از وقفه‌ها — شارژ موجودی قبل از اتمام ترافیک
  • ادغام با CRM/صورتحساب — حسابرسی خودکار هزینه‌های پروکسی در فرآیندهای کسب‌وکار

برای آربیتراژکنندگان که تبلیغات را از طریق چندین حساب کاربری راه‌اندازی می‌کنند، دانستن اینکه کدام پروکسی‌ها فعال هستند و چقدر ترافیک باقی مانده است، حیاتی است — مسدودسازی ناگهانی به دلیل اتمام حد مجاز می‌تواند هزاران دلار از دست دادن سود به همراه داشته باشد. برای آژانس‌های SMM که حساب‌های مشتری را در اینستاگرام یا TikTok مدیریت می‌کنند، اتوماسیون امکان صدور فاکتورهای دقیق برای استفاده از پروکسی را فراهم می‌کند.

پارسرهای بازارهای آنلاین (Wildberries، Ozon، Avito) می‌توانند به‌طور خودکار به پروکسی‌های پشتیبان سوئیچ کنند هنگامی که حد مجاز در پروکسی‌های اصلی به پایان برسد. API امکان ساخت سیستم‌های مقاوم در برابر خطا را فراهم می‌کند که 24/7 بدون دخالت دستی کار می‌کنند.

اصول کار با API ارائه‌دهندگان پروکسی

اکثر ارائه‌دهندگان پروکسی مدرن API های RESTful برای مدیریت سرویس ارائه می‌دهند. API بر اساس یک الگوی استاندارد کار می‌کند: شما یک درخواست HTTP به یک نقطه پایانی خاص با پارامترهای احراز هویت ارسال می‌کنید، و سرور یک JSON با داده‌ها برمی‌گرداند.

جزء API توضیحات مثال
Base URL آدرس پایه API ارائه‌دهنده https://api.provider.com/v1
احراز هویت کلید API یا Bearer Token Authorization: Bearer YOUR_API_KEY
نقاط پایانی مسیرهای خاص برای عملیات مختلف /statistics, /balance
فرمت پاسخ ساختار داده‌ها JSON با فیلدهای status، data، error
Rate Limits محدودیت درخواست‌ها در دقیقه 60-300 درخواست/دقیقه

ساختار معمول JSON پاسخ از API ارائه‌دهنده پروکسی به شکل زیر است:

{
  "status": "success",
  "data": {
    "balance": 1250.50,
    "traffic_used_gb": 45.2,
    "traffic_remaining_gb": 54.8,
    "active_proxies": 15,
    "last_updated": "2024-01-15T10:30:00Z"
  },
  "error": null
}

هنگام کار با API، مهم است که محدودیت‌های نرخ (rate limits) را در نظر بگیرید. اکثر ارائه‌دهندگان اجازه می‌دهند 60-300 درخواست در دقیقه انجام شود. برای نظارت بر آمار، این مقدار بیشتر از حد کافی است — معمولاً درخواست‌ها هر 5-15 دقیقه انجام می‌شوند.

احراز هویت و دریافت کلید API

اولین قدم در کار با API — دریافت کلید احراز هویت است. فرآیند در ارائه‌دهندگان مختلف متفاوت است، اما منطق کلی یکسان است:

راهنمای مرحله به مرحله برای دریافت کلید API:

  1. وارد پنل کاربری ارائه‌دهنده پروکسی شوید
  2. بخش "API" یا "تنظیمات" → "دسترسی API" را پیدا کنید
  3. دکمه "ایجاد کلید API" یا "تولید توکن" را فشار دهید
  4. کلید را کپی کرده و در مکان امنی ذخیره کنید (فقط یک بار نمایش داده می‌شود)
  5. اگر ارائه‌دهنده نیاز به اتصال به آدرس‌های IP دارد، لیست سفید IP را تنظیم کنید
  6. کلید را با یک درخواست آزمایشی از طریق cURL یا Postman بررسی کنید

دو روش اصلی احراز هویت در API ارائه‌دهندگان پروکسی وجود دارد:

روش چگونه کار می‌کند مثال هدر
Bearer Token توکن در هدر Authorization ارسال می‌شود Authorization: Bearer abc123...
کلید API در پارامترها کلید به عنوان پارامتر GET/POST ارسال می‌شود ?api_key=abc123...

مهم: هرگز کلیدهای API را در کدی که به مخزن Git می‌رود ذخیره نکنید. از متغیرهای محیطی (.env files) یا مدیران رمز عبور (AWS Secrets Manager، HashiCorp Vault) استفاده کنید. اگر کلید لو رفت — فوراً آن را در پنل کاربری لغو کرده و یک کلید جدید تولید کنید.

نقاط پایانی اصلی برای دریافت آمار

اگرچه هر ارائه‌دهنده ساختار API خاص خود را دارد، اما اکثر آنها مجموعه استانداردی از نقاط پایانی برای دریافت آمار ارائه می‌دهند. بیایید روش‌های معمول را بررسی کنیم:

نقطه پایانی روش چه چیزی برمی‌گرداند
/balance GET موجودی فعلی و باقی‌مانده ترافیک
/statistics GET آمار کلی استفاده در یک دوره
/statistics/proxy/{id} GET آمار مربوط به یک پروکسی خاص
/sessions/active GET لیست جلسات فعال پروکسی
/traffic/history GET تاریخچه مصرف ترافیک بر اساس روزها
/proxies/list GET لیست تمام پروکسی‌ها با وضعیت‌های آنها

پارامترهای درخواست معمولاً شامل بازه‌های زمانی و فیلترها هستند:

GET /statistics?from=2024-01-01&to=2024-01-15&proxy_type=residential
GET /traffic/history?period=7d&group_by=day
GET /sessions/active?status=online&country=US

برای کار با پروکسی‌های مسکونی، نقطه پایانی دریافت آمار مربوط به جلسات به‌ویژه مهم است، زیرا آنها معمولاً از چرخش IP استفاده می‌کنند. API امکان پیگیری تعداد IP های منحصر به فردی که در یک دوره استفاده شده و حجم ترافیکی که از هر جلسه عبور کرده است را فراهم می‌کند.

مثال‌های کد در Python برای دریافت آمار

Python — محبوب‌ترین زبان برای اتوماسیون کار با پروکسی به لطف کتابخانه requests. بیایید مثال‌های عملی دریافت آمار از طریق API را بررسی کنیم.

درخواست پایه برای موجودی و ترافیک

import requests
import os
from datetime import datetime

# اعتبارنامه API از متغیرهای محیطی
API_KEY = os.getenv('PROXY_API_KEY')
BASE_URL = 'https://api.proxyprovider.com/v1'

def get_balance_statistics():
    """دریافت موجودی و آمار کلی"""
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.get(
            f'{BASE_URL}/balance',
            headers=headers,
            timeout=10
        )
        response.raise_for_status()
        
        data = response.json()
        
        print(f"=== آمار پروکسی در {datetime.now().strftime('%Y-%m-%d %H:%M')} ===")
        print(f"موجودی: ${data['balance']:.2f}")
        print(f"ترافیک مصرف شده: {data['traffic_used_gb']:.2f} GB")
        print(f"باقی‌مانده ترافیک: {data['traffic_remaining_gb']:.2f} GB")
        print(f"پروکسی‌های فعال: {data['active_proxies']}")
        
        return data
        
    except requests.exceptions.RequestException as e:
        print(f"خطا در درخواست: {e}")
        return None

# فراخوانی تابع
stats = get_balance_statistics()

دریافت آمار دقیق بر اساس دوره

from datetime import datetime, timedelta
import requests

def get_traffic_history(days=7):
    """دریافت تاریخچه مصرف ترافیک در N روز"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # محاسبه بازه زمانی
    end_date = datetime.now()
    start_date = end_date - timedelta(days=days)
    
    params = {
        'from': start_date.strftime('%Y-%m-%d'),
        'to': end_date.strftime('%Y-%m-%d'),
        'group_by': 'day'
    }
    
    response = requests.get(
        f'{BASE_URL}/traffic/history',
        headers=headers,
        params=params,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== مصرف ترافیک در {days} روز گذشته ===")
        for day in data['daily_stats']:
            print(f"{day['date']}: {day['traffic_gb']:.2f} GB "
                  f"({day['requests']} درخواست)")
        
        total = sum(day['traffic_gb'] for day in data['daily_stats'])
        print(f"\nجمع کل در دوره: {total:.2f} GB")
        
        return data
    else:
        print(f"خطا {response.status_code}: {response.text}")
        return None

# دریافت آمار برای یک هفته
history = get_traffic_history(7)

نظارت بر آمار پروکسی‌های خاص

def get_proxy_statistics(proxy_id):
    """دریافت آمار مربوط به یک پروکسی خاص"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    response = requests.get(
        f'{BASE_URL}/statistics/proxy/{proxy_id}',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== آمار پروکسی {proxy_id} ===")
        print(f"آدرس IP: {data['ip_address']}")
        print(f"کشور: {data['country']}")
        print(f"نوع: {data['proxy_type']}")
        print(f"وضعیت: {data['status']}")
        print(f"ترافیک مصرف شده: {data['traffic_used_mb']:.2f} MB")
        print(f"تعداد درخواست‌ها: {data['total_requests']}")
        print(f"آخرین فعالیت: {data['last_activity']}")
        
        return data
    else:
        print(f"پروکسی {proxy_id} پیدا نشد")
        return None

def get_all_proxies_stats():
    """دریافت آمار مربوط به تمام پروکسی‌ها"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # ابتدا لیست تمام پروکسی‌ها را دریافت می‌کنیم
    response = requests.get(
        f'{BASE_URL}/proxies/list',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        proxies = response.json()['proxies']
        
        print(f"\n=== آمار مربوط به {len(proxies)} پروکسی ===\n")
        
        total_traffic = 0
        for proxy in proxies:
            stats = get_proxy_statistics(proxy['id'])
            if stats:
                total_traffic += stats['traffic_used_mb']
        
        print(f"\n=== مجموع مصرف ترافیک: {total_traffic/1024:.2f} GB ===")
        
        return proxies
    else:
        print("خطا در دریافت لیست پروکسی‌ها")
        return None

# دریافت آمار مربوط به تمام پروکسی‌ها
all_stats = get_all_proxies_stats()

این مثال‌ها کارکرد پایه‌ای با API را نشان می‌دهند. برای سیستم‌های تولید، مدیریت خطاها، منطق retry در صورت بروز مشکلات شبکه و کش کردن نتایج را اضافه کنید تا از محدودیت‌های نرخ ارائه‌دهنده تجاوز نکنید.

مثال‌های کد در Node.js برای نظارت بر ترافیک

Node.js برای ایجاد میکروسرویس‌های نظارتی که در پس‌زمینه کار می‌کنند و در مواقع بحرانی اعلان می‌فرستند، بسیار مناسب است. از کتابخانه axios برای درخواست‌های HTTP استفاده می‌کنیم.

کلاس پایه برای کار با API پروکسی

const axios = require('axios');
require('dotenv').config();

class ProxyAPIClient {
  constructor() {
    this.baseURL = 'https://api.proxyprovider.com/v1';
    this.apiKey = process.env.PROXY_API_KEY;
    
    this.client = axios.create({
      baseURL: this.baseURL,
      timeout: 10000,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getBalance() {
    try {
      const response = await this.client.get('/balance');
      return response.data;
    } catch (error) {
      console.error('خطا در دریافت موجودی:', error.message);
      throw error;
    }
  }

  async getStatistics(params = {}) {
    try {
      const response = await this.client.get('/statistics', { params });
      return response.data;
    } catch (error) {
      console.error('خطا در دریافت آمار:', error.message);
      throw error;
    }
  }

  async getTrafficHistory(days = 7) {
    const endDate = new Date();
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - days);

    const params = {
      from: startDate.toISOString().split('T')[0],
      to: endDate.toISOString().split('T')[0],
      group_by: 'day'
    };

    try {
      const response = await this.client.get('/traffic/history', { params });
      return response.data;
    } catch (error) {
      console.error('خطا در دریافت تاریخچه ترافیک:', error.message);
      throw error;
    }
  }

  async getProxyStats(proxyId) {
    try {
      const response = await this.client.get(`/statistics/proxy/${proxyId}`);
      return response.data;
    } catch (error) {
      console.error(`خطا در دریافت آمار پروکسی ${proxyId}:`, error.message);
      throw error;
    }
  }
}

module.exports = ProxyAPIClient;

نظارت خودکار با اعلان‌ها

const ProxyAPIClient = require('./ProxyAPIClient');
const nodemailer = require('nodemailer');

class ProxyMonitor {
  constructor(checkIntervalMinutes = 15) {
    this.api = new ProxyAPIClient();
    this.checkInterval = checkIntervalMinutes * 60 * 1000;
    this.thresholds = {
      trafficWarning: 10, // GB - هشدار
      trafficCritical: 5,  // GB - سطح بحرانی
      balanceWarning: 50   // USD - هشدار موجودی
    };
  }

  async checkAndNotify() {
    try {
      const balance = await this.api.getBalance();
      
      console.log(`[${new Date().toISOString()}] بررسی آمار...`);
      console.log(`موجودی: $${balance.balance.toFixed(2)}`);
      console.log(`باقی‌مانده ترافیک: ${balance.traffic_remaining_gb.toFixed(2)} GB`);

      // بررسی آستانه‌های بحرانی
      const alerts = [];

      if (balance.traffic_remaining_gb <= this.thresholds.trafficCritical) {
        alerts.push({
          level: 'critical',
          message: `ترافیک به شدت کم است: ${balance.traffic_remaining_gb.toFixed(2)} GB باقی مانده!`
        });
      } else if (balance.traffic_remaining_gb <= this.thresholds.trafficWarning) {
        alerts.push({
          level: 'warning',
          message: `ترافیک کم است: ${balance.traffic_remaining_gb.toFixed(2)} GB باقی مانده`
        });
      }

      if (balance.balance <= this.thresholds.balanceWarning) {
        alerts.push({
          level: 'warning',
          message: `موجودی کم است: $${balance.balance.toFixed(2)}`
        });
      }

      // ارسال اعلان‌ها
      if (alerts.length > 0) {
        await this.sendAlerts(alerts, balance);
      }

      return { balance, alerts };
    } catch (error) {
      console.error('خطا در نظارت:', error);
      await this.sendErrorNotification(error);
    }
  }

  async sendAlerts(alerts, balance) {
    console.log('\n⚠️  توجه! مشکلاتی شناسایی شده است:');
    alerts.forEach(alert => {
      console.log(`[${alert.level.toUpperCase()}] ${alert.message}`);
    });

    // ارسال ایمیل (تنظیم SMTP)
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
      }
    });

    const emailBody = `
      مشکلاتی در پروکسی شناسایی شده است:
      
      ${alerts.map(a => `- ${a.message}`).join('\n')}
      
      آمار فعلی:
      - موجودی: $${balance.balance.toFixed(2)}
      - باقی‌مانده ترافیک: ${balance.traffic_remaining_gb.toFixed(2)} GB
      - مصرف شده: ${balance.traffic_used_gb.toFixed(2)} GB
      - پروکسی‌های فعال: ${balance.active_proxies}
      
      توصیه می‌شود موجودی را شارژ کنید یا بار را کاهش دهید.
    `;

    await transporter.sendMail({
      from: process.env.ALERT_FROM_EMAIL,
      to: process.env.ALERT_TO_EMAIL,
      subject: '⚠️ هشدار پروکسی',
      text: emailBody
    });
  }

  start() {
    console.log(`شروع نظارت بر پروکسی (بررسی هر ${this.checkInterval / 60000} دقیقه)`);
    
    // اولین بررسی بلافاصله
    this.checkAndNotify();
    
    // بررسی‌های دوره‌ای
    setInterval(() => {
      this.checkAndNotify();
    }, this.checkInterval);
  }
}

// شروع نظارت
const monitor = new ProxyMonitor(15); // بررسی هر 15 دقیقه
monitor.start();

این کد یک سرویس پس‌زمینه ایجاد می‌کند که هر 15 دقیقه آمار را بررسی کرده و در صورت رسیدن به آستانه‌های بحرانی، اعلان‌های ایمیلی ارسال می‌کند. برای پروکسی‌های موبایل، که معمولاً هزینه بیشتری نسبت به پروکسی‌های مسکونی دارند، چنین نظارتی به‌ویژه برای کنترل هزینه‌ها مهم است.

مثال‌های درخواست از طریق cURL

cURL — ابزاری جهانی برای آزمایش API از خط فرمان است. برای بررسی سریع نقاط پایانی و عیب‌یابی ادغام‌ها مفید است.

دریافت موجودی

# درخواست پایه برای موجودی
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# با فرمت زیبا JSON (از طریق jq)
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

# استخراج یک فیلد خاص
curl -s "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.traffic_remaining_gb'

دریافت آمار برای دوره

# آمار برای 7 روز گذشته
curl -X GET "https://api.proxyprovider.com/v1/traffic/history?from=2024-01-08&to=2024-01-15&group_by=day" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.daily_stats'

# آمار مربوط به نوع خاصی از پروکسی
curl -X GET "https://api.proxyprovider.com/v1/statistics?proxy_type=residential&country=US" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

دریافت لیست پروکسی‌های فعال

# لیست تمام پروکسی‌های فعال
curl -X GET "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies[] | {id, ip_address, country, proxy_type}'

# شمارش تعداد پروکسی‌های فعال
curl -s "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies | length'

اسکریپت Bash برای بررسی خودکار

#!/bin/bash

# پیکربندی
API_KEY="YOUR_API_KEY"
BASE_URL="https://api.proxyprovider.com/v1"
TRAFFIC_THRESHOLD=10  # GB - آستانه هشدار

# دریافت آمار
response=$(curl -s "${BASE_URL}/balance" \
  -H "Authorization: Bearer ${API_KEY}")

# تجزیه JSON
traffic_remaining=$(echo "$response" | jq -r '.traffic_remaining_gb')
balance=$(echo "$response" | jq -r '.balance')
active_proxies=$(echo "$response" | jq -r '.active_proxies')

# نمایش آمار
echo "=== آمار پروکسی $(date '+%Y-%m-%d %H:%M:%S') ==="
echo "باقی‌مانده ترافیک: ${traffic_remaining} GB"
echo "موجودی: \$${balance}"
echo "پروکسی‌های فعال: ${active_proxies}"

# بررسی آستانه‌ها
if (( $(echo "$traffic_remaining < $TRAFFIC_THRESHOLD" | bc -l) )); then
  echo "⚠️  توجه: ترافیک کم است! ${traffic_remaining} GB باقی مانده است"
  
  # ارسال اعلان (مثلاً از طریق تلگرام)
  # curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  #   -d chat_id="${TELEGRAM_CHAT_ID}" \
  #   -d text="⚠️ ترافیک پروکسی کم است: ${traffic_remaining} GB"
fi

این اسکریپت را به عنوان check_proxy_stats.sh ذخیره کنید، مجوز اجرایی بدهید (chmod +x check_proxy_stats.sh) و آن را به cron اضافه کنید تا به‌طور خودکار هر ساعت اجرا شود:

0 * * * * /path/to/check_proxy_stats.sh >> /var/log/proxy_monitor.log 2>&1

اتوماسیون نظارت و اعلان‌ها

بررسی دستی آمار غیر مؤثر است — نیاز به اتوماسیون با اعلان‌های هوشمند داریم. بیایید یک سیستم کامل نظارت با ادغام‌ها را بررسی کنیم.

ادغام با تلگرام برای اعلان‌ها

import requests
import os
from datetime import datetime

class TelegramNotifier:
    def __init__(self):
        self.bot_token = os.getenv('TELEGRAM_BOT_TOKEN')
        self.chat_id = os.getenv('TELEGRAM_CHAT_ID')
        self.base_url = f'https://api.telegram.org/bot{self.bot_token}'
    
    def send_message(self, text, parse_mode='Markdown'):
        """ارسال پیام به تلگرام"""
        url = f'{self.base_url}/sendMessage'
        payload = {
            'chat_id': self.chat_id,
            'text': text,
            'parse_mode': parse_mode
        }
        
        try:
            response = requests.post(url, json=payload, timeout=10)
            return response.status_code == 200
        except Exception as e:
            print(f"خطا در ارسال به تلگرام: {e}")
            return False

def monitor_proxy_with_telegram():
    """نظارت با اعلان‌ها در تلگرام"""
    api = ProxyAPIClient()
    notifier = TelegramNotifier()
    
    try:
        balance = api.get_balance()
        
        # تشکیل پیام
        message = f"""
📊 *آمار پروکسی* ({datetime.now().strftime('%H:%M %d.%m.%Y')})

💰 موجودی: ${balance['balance']:.2f}
📈 مصرف شده: {balance['traffic_used_gb']:.2f} GB
📉 باقی‌مانده: {balance['traffic_remaining_gb']:.2f} GB
🔌 پروکسی‌های فعال: {balance['active_proxies']}
        """
        
        # بررسی آستانه‌های بحرانی
        if balance['traffic_remaining_gb'] < 5:
            message += "\n⚠️ *ترافیک به شدت کم است!*"
            notifier.send_message(message)
        elif balance['traffic_remaining_gb'] < 10:
            message += "\n⚡ توصیه می‌شود ترافیک را شارژ کنید"
            notifier.send_message(message)
        
        return balance
        
    except Exception as e:
        error_msg = f"❌ *خطا در نظارت بر پروکسی*\n\n{str(e)}"
        notifier.send_message(error_msg)
        raise

# شروع نظارت
monitor_proxy_with_telegram()

ادغام با Slack

import requests
import json

class SlackNotifier:
    def __init__(self, webhook_url):
        self.webhook_url = webhook_url
    
    def send_alert(self, title, message, level='warning'):
        """ارسال اعلان به Slack"""
        color = {
            'info': '#36a64f',
            'warning': '#ff9900',
            'critical': '#ff0000'
        }.get(level, '#cccccc')
        
        payload = {
            'attachments': [{
                'color': color,
                'title': title,
                'text': message,
                'footer': 'نظارت بر پروکسی',
                'ts': int(datetime.now().timestamp())
            }]
        }
        
        try:
            response = requests.post(
                self.webhook_url,
                data=json.dumps(payload),
                headers={'Content-Type': 'application/json'},
                timeout=10
            )
            return response.status_code == 200
        except Exception as e:
            print(f"خطا در ارسال به Slack: {e}")
            return False

def check_proxy_health():
    """بررسی سلامت پروکسی با اعلان‌ها"""
    api = ProxyAPIClient()
    slack = SlackNotifier(os.getenv('SLACK_WEBHOOK_URL'))
    
    balance = api.get_balance()
    proxies = api.get_all_proxies()
    
    # تحلیل وضعیت
    offline_proxies = [p for p in proxies if p['status'] != 'active']
    
    if len(offline_proxies) > 0:
        message = f"شناسایی {len(offline_proxies)} پروکسی غیر فعال:\n"
        for proxy in offline_proxies[:5]:  # اولین 5
            message += f"- {proxy['ip_address']} ({proxy['country']})\n"
        
        slack.send_alert(
            'پروکسی‌های غیر فعال',
            message,
            level='warning'
        )
    
    if balance['traffic_remaining_gb'] < 5:
        slack.send_alert(
            'ترافیک به شدت کم است!',
            f"باقی‌مانده {balance['traffic_remaining_gb']:.2f} GB. "
            f"موجودی: ${balance['balance']:.2f}",
            level='critical'
        )

check_proxy_health()

تنظیم شارژ خودکار

برخی از ارائه‌دهندگان اجازه می‌دهند از طریق API نه تنها آمار دریافت کنید، بلکه به‌طور خودکار موجودی را هنگام رسیدن به آستانه شارژ کنید:

def auto_topup_if_needed(threshold_gb=10, topup_amount_usd=100):
    """شارژ خودکار در صورت موجودی کم"""
    api = ProxyAPIClient()
    
    balance = api.get_balance()
    
    if balance['traffic_remaining_gb'] < threshold_gb:
        print(f"ترافیک زیر آستانه ({threshold_gb} GB)، شروع شارژ...")
        
        # درخواست برای شارژ از طریق API
        topup_response = requests.post(
            f'{api.base_url}/billing/topup',
            headers={'Authorization': f'Bearer {api.api_key}'},
            json={
                'amount': topup_amount_usd,
                'payment_method': 'card',
                'auto_topup': True
            },
            timeout=10
        )
        
        if topup_response.status_code == 200:
            print(f"✅ موجودی به مبلغ ${topup_amount_usd} شارژ شد")
            
            # ارسال اعلان
            notifier = TelegramNotifier()
            notifier.send_message(
                f"💳 شارژ خودکار\n\n"
                f"مبلغ: ${topup_amount_usd}\n"
                f"باقی‌مانده ترافیک: {balance['traffic_remaining_gb']:.2f} GB\n"
                f"دلیل: رسیدن به آستانه {threshold_gb} GB"
            )
        else:
            print(f"❌ خطا در شارژ: {topup_response.text}")
    else:
        print(f"ترافیک کافی است: {balance['traffic_remaining_gb']:.2f} GB")

# شروع بررسی (می‌توان آن را به cron اضافه کرد)
auto_topup_if_needed()

ایجاد داشبورد آمار شخصی

برای تجسم داده‌ها از API می‌توان یک داشبورد وب با نمودارهای مصرف ترافیک، توزیع بر اساس کشورها و نوع پروکسی‌ها ایجاد کرد. بیایید یک مثال ساده با Flask + Chart.js را بررسی کنیم.

Backend با Flask

from flask import Flask, jsonify, render_template
from datetime import datetime, timedelta
import requests

app = Flask(__name__)

class ProxyDashboard:
    def __init__(self):
        self.api_key = os.getenv('PROXY_API_KEY')
        self.base_url = 'https://api.proxyprovider.com/v1'
    
    def get_dashboard_data(self):
        """دریافت تمام داده‌ها برای داشبورد"""
        headers = {'Authorization': f'Bearer {self.api_key}'}
        
        # موجودی و آمار کلی
        balance = requests.get(
            f'{self.base_url}/balance',
            headers=headers
        ).json()
        
        # تاریخچه برای 30 روز گذشته
        end_date = datetime.now()
        start_date = end_date - timedelta(days=30)
        
        history = requests.get(
            f'{self.base_url}/traffic/history',
            headers=headers,
            params={
                'from': start_date.strftime('%Y-%m-%d'),
                'to': end_date.strftime('%Y-%m-%d'),
                'group_by': 'day'
            }
        ).json()
        
        # لیست پروکسی‌ها
        proxies = requests.get(
            f'{self.base_url}/proxies/list',
            headers=headers
        ).json()
        
        # تجمیع داده‌ها
        traffic_by_country = {}
        traffic_by_type = {}
        
        for proxy in proxies.get('proxies', []):
            country = proxy.get('country', 'Unknown')
            proxy_type = proxy.get('proxy_type', 'Unknown')
            traffic = proxy.get('traffic_used_mb', 0) / 1024  # به GB
            
            traffic_by_country[country] = traffic_by_country.get(country, 0) + traffic
            traffic_by_type[proxy_type] = traffic_by_type.get(proxy_type, 0) + traffic
        
        return {
            'balance': balance,
            'history': history.get('daily_stats', []),
            'traffic_by_country': traffic_by_country,
            'traffic_by_type': traffic_by_type,
            'total_proxies': len(proxies.get('proxies', []))
        }

dashboard = ProxyDashboard()

@app.route('/')
def index():
    """صفحه اصلی داشبورد"""
    return render_template('dashboard.html')

@app.route('/api/stats')
def get_stats():
    """نقطه پایانی API برای دریافت آمار"""
    try:
        data = dashboard.get_dashboard_data()
        return jsonify(data)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, port=5000)

Frontend با نمودارها (dashboard.html)

<!DOCTYPE html>
<html>
<head>
  <title>داشبورد آمار پروکسی</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
    .stats-card { background: white; padding: 20px; margin: 10px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
    .stat-value { font-size: 2rem; font-weight: bold; color: #2563eb; }
    .chart-container { height: 300px; margin: 20px 0; }
  </style>
</head>
<body>
  <h1>📊 داشبورد آمار پروکسی</h1>
  
  <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
    <div class="stats-card">
      <div>موجودی</div>
      <div class="stat-value" id="balance">-</div>
    </div>
    <div class="stats-card">
      <div>باقی‌مانده ترافیک</div>
      <div class="stat-value" id="traffic-remaining">-</div>
    </div>
    <div class="stats-card">
      <div>مصرف شده</div>
      <div class="stat-value" id="traffic-used">-</div>
    </div>
    <div class="stats-card">
      <div>پروکسی‌های فعال</div>
      <div class="stat-value" id="active-proxies">-</div>
    </div>
  </div>

  <div class="chart-container">
    <canvas id="trafficChart"></canvas>
  </div>

  <script>
    async function fetchStats() {
      const response = await fetch('/api/stats');
      const data = await response.json();
      
      document.getElementById('balance').innerText = data.balance.balance;
      document.getElementById('traffic-remaining').innerText = data.balance.traffic_remaining_gb;
      document.getElementById('traffic-used').innerText = data.balance.traffic_used_gb;
      document.getElementById('active-proxies').innerText = data.balance.active_proxies;

      const ctx = document.getElementById('trafficChart').getContext('2d');
      const chart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: data.history.map(stat => stat.date),
          datasets: [{
            label: 'مصرف ترافیک (GB)',
            data: data.history.map(stat => stat.traffic_gb),
            borderColor: 'rgba(75, 192, 192, 1)',
            borderWidth: 2,
            fill: false
          }]
        },
        options: {
          responsive: true,
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }

    fetchStats();
  </script>
</body>
</html>
```