from dotenv import load_dotenvimport osimport discordfrom discord.ext import commandsimport random# Set up the botintents = discord.Intents.default()intents.message_content = Trueintents.reactions = Truebot = commands.Bot(command_prefix="!", intents=intents)@bot.eventasync def on_ready(): print(f"Logged in as {bot.user}")@bot.command()async def hello(ctx): user_name = ctx.author.name greetings = [ f"Hello, {user_name}!", f"Hi, {user_name}! How's it going?", f"Hey there, {user_name}!" ] await ctx.send(random.choice(greetings))@bot.command()async def joke(ctx): jokes = [ "Why don't skeletons fight each other? They don't have the guts!", "Why did the scarecrow win an award? Because he was outstanding in his field!", f"<@{705858372087447663}> at your service! 🫡", "Why don't scientists trust atoms? Because they make up everything!", "What do you call fake spaghetti? An impasta!", "Why did the bicycle fall over? It was two-tired!", "What do you call a can opener that doesn't work? A can't opener!", "Why did the math book look sad? It had too many problems!", "What do you call cheese that isn't yours? Nacho cheese!", "Why did the golfer bring two pairs of pants? In case he got a hole in one!", "Why was the computer cold? It left its Windows open!", ] await ctx.send(random.choice(jokes))@bot.eventasync def on_message(message): if message.author == bot.user: return # Prevent bot from responding to itself # Variations of "thanks" thank_words = ["thanks", "thank you", "thx", "thanks!", "thank u", "thankyou"] if any(word in message.content.lower() for word in thank_words): await message.channel.send(f"You're welcome, {message.author.mention}!") # If someone says "good bot", respond with "Good human!" if "good bot" in message.content.lower(): await message.channel.send("Good human!") await bot.process_commands(message) # Ensures commands still work@bot.eventasync def on_raw_reaction_add(payload): guild = bot.get_guild(payload.guild_id) user = payload.member or await guild.fetch_member(payload.user_id) try: channel = await bot.fetch_channel(payload.channel_id) # ✅ Join thread if it's a forum post (thread) if isinstance(channel, discord.Thread): await channel.join() msg_id = payload.message_id msg_link = f"https://discord.com/channels/{payload.guild_id}/{payload.channel_id}/{msg_id}" # Example message ID and role logic announcement_id = 1362880546769731724 role_id = 1364486096553115679 symposium_role = guild.get_role(role_id) bot_channel = bot.get_channel(1301421202836820047) if payload.emoji.name == "✅": if msg_id == announcement_id: await user.add_roles(symposium_role) if bot_channel: await bot_channel.send(f"Nice job, {user.mention}! {msg_link}") except Exception as e: print(f"Error handling reaction: {e}")# Run the botload_dotenv()bot.run(os.environ["DISCORD_BOT_TOKEN"])
DISCORD_BOT_TOKEN=your_discord_tokenGITHUB_TOKEN=your_github_tokenGITHUB_ORG=your_org_nameSOFTWARE_THREAD_ID=123456789012345678 # ID of your forum thread
Update bot.py
Invites users to the GitHub org
Adds them to the OCR Training team if the org is “Training-Dummy”
Adds them to the Software team if the org is “oc-robotics”
Sends all invite / add-to-team messages to the specified log channel
bot.py
from dotenv import load_dotenvimport osimport discordfrom discord.ext import commandsimport randomimport requests# Load environment variablesload_dotenv()# Set up the botintents = discord.Intents.default()intents.message_content = Trueintents.reactions = Truebot = commands.Bot(command_prefix="!", intents=intents)@bot.eventasync def on_ready(): print(f"Logged in as {bot.user}")@bot.command()async def hello(ctx): user_name = ctx.author.name greetings = [ f"Hello, {user_name}!", f"Hi, {user_name}! How's it going?", f"Hey there, {user_name}!" ] await ctx.send(random.choice(greetings))@bot.command()async def joke(ctx): jokes = [ "Why don't skeletons fight each other? They don't have the guts!", "Why did the scarecrow win an award? Because he was outstanding in his field!", f"<@{705858372087447663}> at your service! 🫡", "Why don't scientists trust atoms? Because they make up everything!", "What do you call fake spaghetti? An impasta!", "Why did the bicycle fall over? It was two-tired!", "What do you call a can opener that doesn't work? A can't opener!", "Why did the math book look sad? It had too many problems!", "What do you call cheese that isn't yours? Nacho cheese!", "Why did the golfer bring two pairs of pants? In case he got a hole in one!", "Why was the computer cold? It left its Windows open!", ] await ctx.send(random.choice(jokes))def github_user_exists(username): url = f"https://api.github.com/users/{username}" response = requests.get(url) return response.status_code == 200def invite_to_github_org(username, org): url = f"https://api.github.com/orgs/{org}/invitations" headers = { "Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}", "Accept": "application/vnd.github+json" } user_data = requests.get(f"https://api.github.com/users/{username}", headers=headers) if user_data.status_code != 200: return False, f"GitHub user `{username}` not found." invitee_id = user_data.json().get("id") data = { "invitee_id": invitee_id, "role": "direct_member" } response = requests.post(url, headers=headers, json=data) if response.status_code in [201, 204]: return True, None return False, response.textdef add_user_to_team(username, org): headers = { "Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}", "Accept": "application/vnd.github+json" } # Map org to team slug team_map = { "Training-Dummy": "ocr-training", "oc-robotics": "software" } team_slug = team_map.get(org) if not team_slug: # No team configured for this org return True, None url = f"https://api.github.com/orgs/{org}/teams/{team_slug}/memberships/{username}" response = requests.put(url, headers=headers) if response.status_code in [200, 201]: return True, None else: return False, response.text@bot.eventasync def on_message(message): if message.author == bot.user: return thank_words = ["thanks", "thank you", "thx", "thanks!", "thank u", "thankyou"] if any(word in message.content.lower() for word in thank_words): await message.channel.send(f"You're welcome, {message.author.mention}!") elif "good bot" in message.content.lower(): await message.channel.send("Good human!") try: target_thread_id = int(os.environ["GITHUB_THREAD_ID"]) log_channel_id = int(os.environ["GITHUB_THREAD_ID"]) log_channel = bot.get_channel(log_channel_id) if isinstance(message.channel, discord.Thread) and message.channel.id == target_thread_id: # Make sure that the message is only one word if len(message.content.strip().split()) != 1: # await message.channel.send("❌ Please provide exactly one GitHub username.") return github_username = message.content.strip().split()[0] if not github_user_exists(github_username): await message.channel.send(f"❌ GitHub user `{github_username}` does not exist.") return confirm_msg = await message.channel.send(f"☑️ React to confirm inviting `{github_username}` to the GitHub Organizations.") await confirm_msg.add_reaction("☑️") def check(reaction, user): return ( user == message.author and str(reaction.emoji) == "☑️" and reaction.message.id == confirm_msg.id ) try: reaction, user = await bot.wait_for("reaction_add", timeout=30.0, check=check) await message.channel.typing() orgs = ["Training-Dummy", "oc-robotics"] for org in orgs: invited, invite_err = invite_to_github_org(github_username, org) if invited: added, add_err = add_user_to_team(github_username, org) if added: await log_channel.send(f"🎉 `{github_username}` invited and added to team for org `{org}`!") else: await log_channel.send(f"✅ Invited `{github_username}` to org `{org}`, but failed to add to team:\n```{add_err}```") else: await log_channel.send(f"❌ Failed to invite `{github_username}` to org `{org}`:\n```{invite_err}```") except Exception as e: await message.channel.send("⚠️ Invite cancelled or timed out.") except Exception as e: await message.channel.send(f"⚠️ An error occurred:\n```{e}```") await bot.process_commands(message)@bot.eventasync def on_raw_reaction_add(payload): guild = bot.get_guild(payload.guild_id) user = payload.member or await guild.fetch_member(payload.user_id) try: channel = await bot.fetch_channel(payload.channel_id) if isinstance(channel, discord.Thread): await channel.join() msg_id = payload.message_id msg_link = f"https://discord.com/channels/{payload.guild_id}/{payload.channel_id}/{msg_id}" announcement_id = 1362880546769731724 role_id = 1364486096553115679 symposium_role = guild.get_role(role_id) bot_channel = bot.get_channel(1301421202836820047) if payload.emoji.name == "✅": if msg_id == announcement_id: await user.add_roles(symposium_role) if bot_channel: await bot_channel.send(f"Nice job, {user.mention}! {msg_link}") except Exception as e: print(f"Error handling reaction: {e}")bot.run(os.environ["DISCORD_BOT_TOKEN"])