You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在同一应用中运行Flask与Discord Bot的技术实现问询

Hey there! I’ve worked on similar setups before, so let’s walk through how to run your discord.py bot and Flask web server side-by-side to handle Twitch webhooks. Here’s a practical, step-by-step solution:

Core Idea

The problem here is that both discord.py and Flask run their own event loops—if you start one after the other, the second one will never run because the first blocks the thread. The simplest fix is to run Flask in a separate daemon thread, so it runs in the background while your Discord bot handles its own events.

Step 1: Install Dependencies

First, make sure you have all the required packages installed:

pip install discord.py flask requests
Step 2: Full Code Example

Here’s a complete, working script that ties everything together. I’ll break down the key parts below:

import discord
from discord.ext import commands
from flask import Flask, request, abort
import threading
import hmac
import hashlib

# ----------------------
# Discord Bot Configuration
# ----------------------
intents = discord.Intents.default()
intents.message_content = True  # Required to send messages in channels
bot = commands.Bot(command_prefix="!", intents=intents)

# ----------------------
# Flask Webhook Configuration
# ----------------------
app = Flask(__name__)
TWITCH_WEBHOOK_SECRET = "your_twitch_webhook_secret"  # From Twitch Dev Console
TARGET_DISCORD_CHANNEL_ID = 123456789012345678  # Replace with your channel ID

# ----------------------
# Discord Bot Events
# ----------------------
@bot.event
async def on_ready():
    print(f"Logged in as {bot.user} (ID: {bot.user.id})")
    print("Bot is ready to handle Twitch events!")
    print("----------------------------------------")

# ----------------------
# Twitch Webhook Endpoints
# ----------------------
# Handle Twitch's webhook verification (GET request)
@app.route("/twitch-webhook", methods=["GET"])
def verify_webhook():
    challenge = request.args.get("hub.challenge")
    if challenge:
        return challenge, 200
    abort(400)  # Bad request if no challenge provided

# Handle Twitch event notifications (POST request)
@app.route("/twitch-webhook", methods=["POST"])
def handle_twitch_event():
    # Optional: Verify Twitch's request signature to prevent spam
    signature_header = request.headers.get("X-Hub-Signature")
    if not signature_header:
        abort(403)  # Forbidden if no signature
    
    # Validate the signature using your webhook secret
    sha1_hash = hmac.new(
        TWITCH_WEBHOOK_SECRET.encode(),
        request.data,
        hashlib.sha1
    ).hexdigest()
    if not signature_header == f"sha1={sha1_hash}":
        abort(403)  # Invalid signature
    
    # Parse the event data
    event_data = request.json
    event_type = event_data["event"]["type"]
    
    # Handle stream online event
    if event_type == "stream.online":
        streamer_name = event_data["event"]["broadcaster_user_name"]
        streamer_login = event_data["event"]["broadcaster_user_login"]
        
        # Send message to Discord using the bot's event loop
        channel = bot.get_channel(TARGET_DISCORD_CHANNEL_ID)
        if channel:
            # Use bot.loop.create_task to run async code in Flask's sync thread
            bot.loop.create_task(
                channel.send(f"🎉 {streamer_name} just went live on Twitch!\nWatch here: https://twitch.tv/{streamer_login}")
            )
    
    return "", 200  # Twitch expects a 200 OK response

# ----------------------
# Run Both Services
# ----------------------
def run_flask_server():
    # Use host='0.0.0.0' to make the server accessible externally
    # Disable debug in production!
    app.run(host="0.0.0.0", port=5000, debug=False)

if __name__ == "__main__":
    # Start Flask in a daemon thread (dies when main thread exits)
    flask_thread = threading.Thread(target=run_flask_server)
    flask_thread.daemon = True
    flask_thread.start()
    
    # Start the Discord Bot
    bot.run("your_discord_bot_token")  # Replace with your bot token
Key Notes & Fixes
  • Twitch Signature Verification: I added optional (but highly recommended) signature validation to ensure only Twitch can send requests to your webhook. You’ll get the secret when you set up the webhook in the Twitch Developer Console.
  • Async Compatibility: Flask runs in a synchronous thread, so we can’t use await directly. Instead, we use bot.loop.create_task() to schedule the Discord message send in the bot’s async event loop—this avoids blocking Flask and keeps everything working smoothly.
  • Local Development: To test locally, you’ll need a tool like ngrok to expose your Flask server to the internet. Run ngrok http 5000 and use the provided HTTPS URL as your Twitch webhook callback.
  • Discord Intents: Don’t forget to enable the message_content intent in the Discord Developer Portal for your bot—otherwise, it won’t be able to send messages.
  • Production Deployment: For production, use a proper WSGI server like Gunicorn instead of Flask’s built-in server, and store secrets (bot token, Twitch secret) as environment variables instead of hardcoding them.

内容的提问来源于stack exchange,提问作者Haxo201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:36:23