部署至Digital Ocean后AFK功能失效的技术求助
Let's break down why your AFK command stopped working after deploying to Digital Ocean—even without changing code. Here are the most likely culprits and actionable fixes:
Key Issues Identified
Discord Intents Misconfiguration
When running locally, your bot might have gotten away with default intents (Discord is more lenient for small/test servers), but on production servers, explicit intents are required to access member data and message content. Without these,message.mentionsmight returnUserobjects instead ofMemberobjects, which don't match theMemberobjects stored in yourafkdict. This explains why ping alerts don't trigger, and why only manual command calls (which usectx.author, aMemberobject) can cancel AFK.Unreliable Object Matching
StoringMember/Userobjects directly inafkdictis risky—different instances of the same user object (from bot restarts or cache refreshes) have unique hashes, so they won't be recognized as the same key in the dictionary.
Step-by-Step Fixes
1. Enable Required Privileged Intents
First, update your bot's settings in the Discord Developer Portal:
- Go to your bot application → Privileged Gateway Intents
- Enable both
Server Members IntentandMessage Content Intent - Save changes and restart your bot on Digital Ocean
2. Update Code to Use User IDs Instead of Objects
Replace your existing code with this version, which uses user IDs (converted to strings for consistency) instead of objects for reliable matching:
import discord from discord.ext import commands # Configure required intents intents = discord.Intents.default() intents.members = True intents.message_content = True client = commands.Bot(command_prefix="YOUR_PREFIX_HERE", intents=intents) # AFK storage: key = user ID (str), value = afk message afkdict = {} @client.command( name="afk", brief="Away From Keyboard", description="Set your AFK status with an optional message. I'll alert anyone who pings you until you return." ) async def afk(ctx, message="They didn't leave a message!"): global afkdict user_id = str(ctx.author.id) if user_id in afkdict: afkdict.pop(user_id) await ctx.send(f"Welcome back {ctx.author.mention}! You're no longer AFK.") else: afkdict[user_id] = message await ctx.send(f"{ctx.author.mention}, you're now AFK. Enjoy your break!") @client.event async def on_message(message): global afkdict user_id = str(message.author.id) # Auto-cancel AFK when user sends a message if user_id in afkdict: afkdict.pop(user_id) await message.channel.send(f"Welcome back {message.author.mention}! You're no longer AFK.") # Alert pingers about AFK users for member in message.mentions: member_id = str(member.id) if member_id != user_id and member_id in afkdict: afk_msg = afkdict[member_id] await message.channel.send(f"Oops! {member.mention} is AFK right now. {afk_msg}") # Don't forget to process commands! await client.process_commands(message) # Run your bot client.run("YOUR_BOT_TOKEN_HERE")
3. Optional: Add Persistence (Avoid Losing AFK Status on Restart)
If you want AFK status to survive bot restarts (common with cloud hosting), add file-based storage using JSON:
import json import os # Add these functions above the afk command AFK_STORAGE = "afk_data.json" def load_afk_data(): if os.path.exists(AFK_STORAGE): with open(AFK_STORAGE, "r") as f: return json.load(f) return {} def save_afk_data(data): with open(AFK_STORAGE, "w") as f: json.dump(data, f, indent=2) # Initialize afkdict with saved data afkdict = load_afk_data() # Update the afk command to save changes @client.command(...) async def afk(ctx, message="..."): global afkdict user_id = str(ctx.author.id) if user_id in afkdict: afkdict.pop(user_id) await ctx.send(f"Welcome back {ctx.author.mention}! You're no longer AFK.") else: afkdict[user_id] = message await ctx.send(f"{ctx.author.mention}, you're now AFK. Enjoy your break!") save_afk_data(afkdict) # Save after every change # Update on_message to save when AFK is auto-canceled @client.event async def on_message(message): global afkdict user_id = str(message.author.id) if user_id in afkdict: afkdict.pop(user_id) await message.channel.send(f"Welcome back {message.author.mention}! You're no longer AFK.") save_afk_data(afkdict) # Save after auto-cancel # ... rest of the on_message code ...
Why This Works
- Using user IDs ensures consistent matching regardless of object instances or cache states.
- Enabling intents lets your bot properly access member data and message content on production servers.
- Optional persistence prevents AFK status from being lost if your bot restarts (common with cloud hosting).
内容的提问来源于stack exchange,提问作者Kali

