Fixed discord oauth2 integration, it was giving a 500 error on the first attempt. It should work properly now.
This commit is contained in:
parent
0c74366e4a
commit
67a80cdca1
@ -52,6 +52,24 @@ async def on_member_join(member):
|
|||||||
logger.error(f"Failed to add Member role to {member.name}: {str(e)}")
|
logger.error(f"Failed to add Member role to {member.name}: {str(e)}")
|
||||||
else:
|
else:
|
||||||
logger.error(f"'Member' role not found in the server")
|
logger.error(f"'Member' role not found in the server")
|
||||||
|
|
||||||
|
# Send a welcome DM to the new member
|
||||||
|
try:
|
||||||
|
welcome_message = (
|
||||||
|
f"Welcome to the Resonance Rumble Discord server, {member.name}!\n\n"
|
||||||
|
"We're excited to have you join our community. Here are a few things to get you started:\n"
|
||||||
|
"• Come play the game here https://resonancerumble.com\n"
|
||||||
|
"• Introduce yourself in the #introductions channel.\n"
|
||||||
|
"• If you need any help, feel free to ask in the #help channel.\n\n"
|
||||||
|
"Don't forget to link your Discord account in the game to unlock an exclusive class!\n"
|
||||||
|
"Have fun and happy rumbling!"
|
||||||
|
)
|
||||||
|
await member.send(welcome_message)
|
||||||
|
logger.info(f"Sent welcome DM to {member.name}")
|
||||||
|
except discord.Forbidden:
|
||||||
|
logger.error(f"Failed to send welcome DM to {member.name}: User has DMs disabled")
|
||||||
|
except discord.HTTPException as e:
|
||||||
|
logger.error(f"Failed to send welcome DM to {member.name}: {str(e)}")
|
||||||
|
|
||||||
async def class_autocomplete(interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
|
async def class_autocomplete(interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
|
||||||
classes = classes_collection.find({}, {"name": 1})
|
classes = classes_collection.find({}, {"name": 1})
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import requests
|
|||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
import secrets
|
import secrets
|
||||||
from werkzeug.http import generate_etag
|
from werkzeug.http import generate_etag
|
||||||
|
import discord
|
||||||
|
import asyncio
|
||||||
from config import DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI, DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, ACCOUNT_LINKED_ROLE_ID, DISCORD_WEBHOOK_URL
|
from config import DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI, DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, ACCOUNT_LINKED_ROLE_ID, DISCORD_WEBHOOK_URL
|
||||||
|
|
||||||
secret_key = secrets.token_hex(16)
|
secret_key = secrets.token_hex(16)
|
||||||
@ -85,6 +87,25 @@ main_room = 'main_game_room'
|
|||||||
MAP_WIDTH = 3000
|
MAP_WIDTH = 3000
|
||||||
MAP_HEIGHT = 2000
|
MAP_HEIGHT = 2000
|
||||||
|
|
||||||
|
async def send_discord_dm(user_id, message):
|
||||||
|
try:
|
||||||
|
intents = discord.Intents.default()
|
||||||
|
intents.members = True
|
||||||
|
client = discord.Client(intents=intents)
|
||||||
|
await client.login(DISCORD_BOT_TOKEN)
|
||||||
|
|
||||||
|
user = await client.fetch_user(user_id)
|
||||||
|
if user:
|
||||||
|
await user.send(message)
|
||||||
|
print(f"Sent achievement DM to user {user_id}")
|
||||||
|
else:
|
||||||
|
print(f"Couldn't find Discord user with ID {user_id}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error sending Discord DM: {str(e)}")
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
def award_achievement(user_id, achievement_id):
|
def award_achievement(user_id, achievement_id):
|
||||||
user = users_collection.find_one({'_id': ObjectId(user_id)})
|
user = users_collection.find_one({'_id': ObjectId(user_id)})
|
||||||
if not user:
|
if not user:
|
||||||
@ -105,6 +126,15 @@ def award_achievement(user_id, achievement_id):
|
|||||||
|
|
||||||
send_discord_alert(f"🏆 Player {user['username']} has earned the '{achievement['name']}' achievement!", user['username'])
|
send_discord_alert(f"🏆 Player {user['username']} has earned the '{achievement['name']}' achievement!", user['username'])
|
||||||
|
|
||||||
|
# Send a DM to the user if they have a linked Discord account
|
||||||
|
if 'discord_id' in user:
|
||||||
|
achievement_message = (
|
||||||
|
f"Congratulations! You've earned the '{achievement['name']}' achievement in Resonance Rumble!\n\n"
|
||||||
|
f"Achievement description: {achievement['description']}\n\n"
|
||||||
|
"Keep up the great work and continue resonating!"
|
||||||
|
)
|
||||||
|
asyncio.run(send_discord_dm(user['discord_id'], achievement_message))
|
||||||
|
|
||||||
# Check for classes to unlock
|
# Check for classes to unlock
|
||||||
classes_to_unlock = list(classes_collection.find({'unlock_requirements.achievement': achievement_id}))
|
classes_to_unlock = list(classes_collection.find({'unlock_requirements.achievement': achievement_id}))
|
||||||
for class_doc in classes_to_unlock:
|
for class_doc in classes_to_unlock:
|
||||||
@ -118,6 +148,7 @@ def award_achievement(user_id, achievement_id):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send_discord_alert(message, username=None):
|
def send_discord_alert(message, username=None):
|
||||||
if username:
|
if username:
|
||||||
user = users_collection.find_one({'username': username})
|
user = users_collection.find_one({'username': username})
|
||||||
@ -295,10 +326,14 @@ def initiate_discord_link(user_id):
|
|||||||
|
|
||||||
@app.route('/discord-callback')
|
@app.route('/discord-callback')
|
||||||
def discord_callback():
|
def discord_callback():
|
||||||
|
logging.info("Discord callback route hit")
|
||||||
code = request.args.get('code')
|
code = request.args.get('code')
|
||||||
state = request.args.get('state')
|
state = request.args.get('state')
|
||||||
|
|
||||||
|
logging.info(f"Received code: {code}, state: {state}")
|
||||||
|
|
||||||
if not code or not state:
|
if not code or not state:
|
||||||
|
logging.error("Missing code or state")
|
||||||
return "Error: Missing parameters", 400
|
return "Error: Missing parameters", 400
|
||||||
|
|
||||||
# Verify state and get user_id
|
# Verify state and get user_id
|
||||||
@ -308,9 +343,11 @@ def discord_callback():
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not oauth_state:
|
if not oauth_state:
|
||||||
|
logging.error("Invalid or expired state")
|
||||||
return "Error: Invalid or expired state", 400
|
return "Error: Invalid or expired state", 400
|
||||||
|
|
||||||
user_id = oauth_state['user_id']
|
user_id = oauth_state['user_id']
|
||||||
|
logging.info(f"Valid state for user_id: {user_id}")
|
||||||
|
|
||||||
# Exchange code for token
|
# Exchange code for token
|
||||||
data = {
|
data = {
|
||||||
@ -323,50 +360,60 @@ def discord_callback():
|
|||||||
headers = {
|
headers = {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
}
|
}
|
||||||
|
logging.info("Exchanging code for token")
|
||||||
r = requests.post(f'{DISCORD_API_ENDPOINT}/oauth2/token', data=data, headers=headers)
|
r = requests.post(f'{DISCORD_API_ENDPOINT}/oauth2/token', data=data, headers=headers)
|
||||||
|
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
|
logging.error(f"Failed to exchange code for token. Status: {r.status_code}, Response: {r.text}")
|
||||||
return "Error: Failed to exchange code for token", 400
|
return "Error: Failed to exchange code for token", 400
|
||||||
|
|
||||||
tokens = r.json()
|
tokens = r.json()
|
||||||
|
logging.info("Successfully exchanged code for token")
|
||||||
|
|
||||||
# Get user info
|
# Get user info
|
||||||
headers = {
|
headers = {
|
||||||
'Authorization': f'Bearer {tokens["access_token"]}'
|
'Authorization': f'Bearer {tokens["access_token"]}'
|
||||||
}
|
}
|
||||||
|
logging.info("Getting user info from Discord")
|
||||||
r = requests.get(f'{DISCORD_API_ENDPOINT}/users/@me', headers=headers)
|
r = requests.get(f'{DISCORD_API_ENDPOINT}/users/@me', headers=headers)
|
||||||
|
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
|
logging.error(f"Failed to get user info. Status: {r.status_code}, Response: {r.text}")
|
||||||
return "Error: Failed to get user info", 400
|
return "Error: Failed to get user info", 400
|
||||||
|
|
||||||
user_data = r.json()
|
user_data = r.json()
|
||||||
|
logging.info(f"Retrieved user info for Discord user: {user_data['username']}#{user_data['discriminator']}")
|
||||||
|
|
||||||
# Update user in database
|
# Update user in database
|
||||||
users_collection.update_one(
|
try:
|
||||||
{'_id': ObjectId(user_id)},
|
result = users_collection.update_one(
|
||||||
{'$set': {
|
{'_id': ObjectId(user_id)},
|
||||||
'discord_id': user_data['id'],
|
{'$set': {
|
||||||
'discord_username': f"{user_data['username']}#{user_data['discriminator']}",
|
'discord_id': user_data['id'],
|
||||||
'discord_avatar': user_data['avatar']
|
'discord_username': f"{user_data['username']}#{user_data['discriminator']}",
|
||||||
}}
|
'discord_avatar': user_data['avatar']
|
||||||
)
|
}}
|
||||||
|
)
|
||||||
|
logging.info(f"Updated user in database. Modified count: {result.modified_count}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to update user in database: {str(e)}")
|
||||||
|
return "Error: Failed to update user information", 500
|
||||||
|
|
||||||
# Award the achievement
|
# Award the achievement
|
||||||
if award_achievement(user_id, 'discord_linked'):
|
if award_achievement(user_id, 'discord_linked'):
|
||||||
socketio.emit('achievement_unlocked', {
|
logging.info(f"User {user_id} unlocked the 'Discord Linked' achievement")
|
||||||
'achievement_id': 'discord_linked',
|
|
||||||
'name': 'Discord Linked',
|
|
||||||
'description': 'Successfully linked your Discord account',
|
|
||||||
'image': 'discord_achievement.png'
|
|
||||||
}, room=request.sid)
|
|
||||||
|
|
||||||
|
# Add Discord role
|
||||||
|
try:
|
||||||
|
add_discord_role(user_data['id'], ACCOUNT_LINKED_ROLE_ID)
|
||||||
|
logging.info(f"Added Discord role to user {user_data['id']}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to add Discord role: {str(e)}")
|
||||||
|
|
||||||
# After successfully updating the user in the database:
|
logging.info("Discord callback completed successfully")
|
||||||
add_discord_role(user_data['id'], ACCOUNT_LINKED_ROLE_ID)
|
|
||||||
|
|
||||||
|
|
||||||
return """
|
return """
|
||||||
<script>
|
<script>
|
||||||
|
console.log("Discord link successful. Closing window...");
|
||||||
window.opener.postMessage('discord-linked', '*');
|
window.opener.postMessage('discord-linked', '*');
|
||||||
window.close();
|
window.close();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user