|
import json |
|
import hmac |
|
import hashlib |
|
from http.server import BaseHTTPRequestHandler, HTTPServer |
|
import logging |
|
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
WEBHOOK_SECRET = "your-base64-encoded-secret" |
|
|
|
class WebhookHandler(BaseHTTPRequestHandler): |
|
def do_POST(self): |
|
try: |
|
|
|
content_length = int(self.headers['Content-Length']) |
|
post_data = self.rfile.read(content_length).decode('utf-8') |
|
payload = json.loads(post_data) |
|
|
|
|
|
signature = self.headers.get('X-Daily-Signature') |
|
if not self.verify_signature(post_data, signature): |
|
logger.warning("Invalid webhook signature") |
|
self.send_response(401) |
|
self.end_headers() |
|
return |
|
|
|
|
|
event_type = payload.get('event') |
|
if event_type in ['dialin.connected', 'dialin.stopped']: |
|
logger.info(f"Received {event_type} event: {json.dumps(payload, indent=2)}") |
|
|
|
|
|
if event_type == 'dialin.connected': |
|
call_id = payload.get('callId') |
|
caller = payload.get('From') |
|
logger.info(f"Dial-in connected: Call ID {call_id} from {caller}") |
|
|
|
self.handle_dialin_connected(payload) |
|
elif event_type == 'dialin.stopped': |
|
call_id = payload.get('callId') |
|
logger.info(f"Dial-in stopped: Call ID {call_id}") |
|
|
|
|
|
self.send_response(200) |
|
self.send_header('Content-type', 'application/json') |
|
self.end_headers() |
|
self.wfile.write(b'{"status": "Event received"}') |
|
else: |
|
logger.info(f"Ignored event type: {event_type}") |
|
self.send_response(200) |
|
self.end_headers() |
|
|
|
except Exception as e: |
|
logger.error(f"Error processing webhook: {str(e)}") |
|
self.send_response(500) |
|
self.end_headers() |
|
|
|
def verify_signature(self, payload, signature): |
|
"""Verify the webhook signature using HMAC-SHA256.""" |
|
if not signature or not WEBHOOK_SECRET: |
|
return False |
|
computed = hmac.new( |
|
WEBHOOK_SECRET.encode('utf-8'), |
|
payload.encode('utf-8'), |
|
hashlib.sha256 |
|
).hexdigest() |
|
return hmac.compare_digest(computed, signature) |
|
|
|
def handle_dialin_connected(self, payload): |
|
"""Handle dialin.connected event (e.g., trigger bot startup).""" |
|
|
|
import requests |
|
start_url = "https://<your-space>.hf.space/start" |
|
try: |
|
response = requests.post(start_url, json=payload, timeout=5) |
|
logger.info(f"Sent to /start: {response.status_code} - {response.text}") |
|
except requests.RequestException as e: |
|
logger.error(f"Failed to send to /start: {str(e)}") |
|
|
|
def run(server_class=HTTPServer, handler_class=WebhookHandler, port=8000): |
|
server_address = ('', port) |
|
httpd = server_class(server_address, handler_class) |
|
logger.info(f"Starting webhook server on port {port}...") |
|
httpd.serve_forever() |
|
|
|
if __name__ == '__main__': |
|
run() |