From 95db0d47c29844db102a3a92e0880ac522c1fb05 Mon Sep 17 00:00:00 2001 From: Rushil Umaretiya <2023rumareti@tjhsst.edu> Date: Wed, 28 Oct 2020 20:49:45 -0400 Subject: [PATCH] finished first part of bot --- .env.sample | 5 ++ .gitignore | 4 ++ Pipfile | 14 ++++ Pipfile.lock | 156 +++++++++++++++++++++++++++++++++++++++++ readme.md => README.md | 0 bot.py | 151 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 330 insertions(+) create mode 100644 .env.sample create mode 100644 Pipfile create mode 100644 Pipfile.lock rename readme.md => README.md (100%) create mode 100644 bot.py diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..6c867b2 --- /dev/null +++ b/.env.sample @@ -0,0 +1,5 @@ +ION_API_URL = '' +ION_USER = '' +ION_PASS = '' +DISCORD_TOKEN = '' +DISCORD_GUILD='' \ No newline at end of file diff --git a/.gitignore b/.gitignore index b8cfaab..695b003 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# disc bot +.env +err.log + #led / optimized / DLL files __pycache__/ *.py[cod] diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..e0a1db3 --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +"discord.py" = "*" +requests = "*" +python-dotenv = "*" + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..f5bcd23 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,156 @@ +{ + "_meta": { + "hash": { + "sha256": "a4fb8a8833f84a75c80b183abe16b17ceb6f81ce715493792ad6ab105a6ed99e" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiohttp": { + "hashes": [ + "sha256:1a4160579ffbc1b69e88cb6ca8bb0fbd4947dfcbf9fb1e2a4fc4c7a4a986c1fe", + "sha256:206c0ccfcea46e1bddc91162449c20c72f308aebdcef4977420ef329c8fcc599", + "sha256:2ad493de47a8f926386fa6d256832de3095ba285f325db917c7deae0b54a9fc8", + "sha256:319b490a5e2beaf06891f6711856ea10591cfe84fe9f3e71a721aa8f20a0872a", + "sha256:470e4c90da36b601676fe50c49a60d34eb8c6593780930b1aa4eea6f508dfa37", + "sha256:60f4caa3b7f7a477f66ccdd158e06901e1d235d572283906276e3803f6b098f5", + "sha256:66d64486172b032db19ea8522328b19cfb78a3e1e5b62ab6a0567f93f073dea0", + "sha256:687461cd974722110d1763b45c5db4d2cdee8d50f57b00c43c7590d1dd77fc5c", + "sha256:698cd7bc3c7d1b82bb728bae835724a486a8c376647aec336aa21a60113c3645", + "sha256:797456399ffeef73172945708810f3277f794965eb6ec9bd3a0c007c0476be98", + "sha256:a885432d3cabc1287bcf88ea94e1826d3aec57fd5da4a586afae4591b061d40d", + "sha256:c506853ba52e516b264b106321c424d03f3ddef2813246432fa9d1cefd361c81", + "sha256:fb83326d8295e8840e4ba774edf346e87eca78ba8a89c55d2690352842c15ba5" + ], + "markers": "python_full_version >= '3.5.3'", + "version": "==3.6.3" + }, + "async-timeout": { + "hashes": [ + "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", + "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" + ], + "markers": "python_full_version >= '3.5.3'", + "version": "==3.0.1" + }, + "attrs": { + "hashes": [ + "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", + "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.2.0" + }, + "certifi": { + "hashes": [ + "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", + "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" + ], + "version": "==2020.6.20" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "discord.py": { + "hashes": [ + "sha256:2367359e31f6527f8a936751fc20b09d7495dd6a76b28c8fb13d4ca6c55b7563", + "sha256:def00dc50cf36d21346d71bc89f0cad8f18f9a3522978dc18c7796287d47de8b" + ], + "index": "pypi", + "version": "==1.5.1" + }, + "idna": { + "hashes": [ + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.10" + }, + "multidict": { + "hashes": [ + "sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a", + "sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000", + "sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2", + "sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507", + "sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5", + "sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7", + "sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d", + "sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463", + "sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19", + "sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3", + "sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b", + "sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c", + "sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87", + "sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7", + "sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430", + "sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255", + "sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d" + ], + "markers": "python_version >= '3.5'", + "version": "==4.7.6" + }, + "python-dotenv": { + "hashes": [ + "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e", + "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0" + ], + "index": "pypi", + "version": "==0.15.0" + }, + "requests": { + "hashes": [ + "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b", + "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898" + ], + "index": "pypi", + "version": "==2.24.0" + }, + "urllib3": { + "hashes": [ + "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", + "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "version": "==1.25.11" + }, + "yarl": { + "hashes": [ + "sha256:040b237f58ff7d800e6e0fd89c8439b841f777dd99b4a9cca04d6935564b9409", + "sha256:17668ec6722b1b7a3a05cc0167659f6c95b436d25a36c2d52db0eca7d3f72593", + "sha256:3a584b28086bc93c888a6c2aa5c92ed1ae20932f078c46509a66dce9ea5533f2", + "sha256:4439be27e4eee76c7632c2427ca5e73703151b22cae23e64adb243a9c2f565d8", + "sha256:48e918b05850fffb070a496d2b5f97fc31d15d94ca33d3d08a4f86e26d4e7c5d", + "sha256:9102b59e8337f9874638fcfc9ac3734a0cfadb100e47d55c20d0dc6087fb4692", + "sha256:9b930776c0ae0c691776f4d2891ebc5362af86f152dd0da463a6614074cb1b02", + "sha256:b3b9ad80f8b68519cc3372a6ca85ae02cc5a8807723ac366b53c0f089db19e4a", + "sha256:bc2f976c0e918659f723401c4f834deb8a8e7798a71be4382e024bcc3f7e23a8", + "sha256:c22c75b5f394f3d47105045ea551e08a3e804dc7e01b37800ca35b58f856c3d6", + "sha256:c52ce2883dc193824989a9b97a76ca86ecd1fa7955b14f87bf367a61b6232511", + "sha256:ce584af5de8830d8701b8979b18fcf450cef9a382b1a3c8ef189bedc408faf1e", + "sha256:da456eeec17fa8aa4594d9a9f27c0b1060b6a75f2419fe0c00609587b2695f4a", + "sha256:db6db0f45d2c63ddb1a9d18d1b9b22f308e52c83638c26b422d520a815c4b3fb", + "sha256:df89642981b94e7db5596818499c4b2219028f2a528c9c37cc1de45bf2fd3a3f", + "sha256:f18d68f2be6bf0e89f1521af2b1bb46e66ab0018faafa81d70f358153170a317", + "sha256:f379b7f83f23fe12823085cd6b906edc49df969eb99757f58ff382349a3303c6" + ], + "markers": "python_version >= '3.5'", + "version": "==1.5.1" + } + }, + "develop": {} +} diff --git a/readme.md b/README.md similarity index 100% rename from readme.md rename to README.md diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..e55832c --- /dev/null +++ b/bot.py @@ -0,0 +1,151 @@ +import os +import random +import requests +from collections.abc import Sequence +import discord +from discord.ext import commands +from discord.utils import get +from dotenv import load_dotenv + + +load_dotenv() + +TOKEN = os.getenv('DISCORD_TOKEN') +GUILD = os.getenv('DISCORD_GUILD') +ION_API_URL = os.getenv('ION_API_URL') +ION_USER = os.getenv('ION_USER') +ION_PASS = os.getenv('ION_PASS') +ADMIN_ROLE = os.getenv('ADMIN_ROLE') +STUDENT_ROLE = os.getenv('STUDENT_ROLE') + +intents = discord.Intents.all() +bot = commands.Bot(command_prefix='$', intents=intents) + +@bot.event +async def on_ready(): + guild = await bot.fetch_guild(GUILD) + print(f'Logged in as {bot.user.name} on {guild}') + +def make_sequence(seq): + if seq is None: + return () + if isinstance(seq, Sequence) and not isinstance(seq, str): + return seq + else: + return (seq,) + +def message_check(channel=None, author=None, content=None, ignore_bot=True, lower=True): + channel = make_sequence(channel) + author = make_sequence(author) + content = make_sequence(content) + if lower: + content = tuple(c.lower() for c in content) + def check(message): + if ignore_bot and message.author.bot: + return False + if channel and message.channel not in channel: + return False + if author and message.author not in author: + return False + actual_content = message.content.lower() if lower else message.content + if content and actual_content not in content: + return False + return True + return check + +@bot.event +async def on_member_join(member): + + await member.create_dm() + await member.dm_channel.send( + f'Hey {member.name}, you\'re almost ready to get into the action! Just reply to me with your `Ion` username (e.g. 2023sstern) and I\'ll verify you!' + ) + verify = False + attempts = 5 + while not verify and attempts > 0: + attempts -= 1 + + reply = await bot.wait_for("message", check=message_check(channel=member.dm_channel)) + print ('reply: ' + reply.content) + try: + response = requests.get(ION_API_URL+f'/profile/{reply.content}', auth=requests.auth.HTTPBasicAuth(ION_USER, ION_PASS)).json() + nick = response['full_name'] + grade = response['grade']['name'] + first_name = response['first_name'] + except: + response, nick, first_name = None, None, None + + if nick != None: + if grade == 'sophomore': + guild = await bot.fetch_guild(GUILD) + role = get(guild.roles, name="Student") + await member.add_roles(role) + print(nick) + await member.edit(nick=nick) + await member.dm_channel.send( + f'Good stuff :sparkles:{member.mention}:sparkles:, you just got the Student role on the TJ 2023 discord server, and you should be able to access all the channels!' + f'```don\'t go too wild```' + ) + break + else: + await member.dm_channel.send( + f'Woah there buckaroo, this server is for 2023 gang only. Watch it.' + ) + await member.dm_channel.send( + f'Sorry, but that didn\'t work, please just put your Ion username and nothing else (e.g. `2023sstern`)' + f'You have {attempts} attempts remaining.' + ) + else: + await member.dm_channel.send( + f'Bummer dude, but don\'t worry, just DM any of the Class 🅱️ouncil (@Rushilwiz#4303) and they\'ll get it fixed for u ;)' + ) + +@bot.command(name='schedule', help='Gets schedule off Ion') +async def schedule(ctx): + schedule = requests.get(ION_API_URL+'/schedule', auth=requests.auth.HTTPBasicAuth(ION_USER, ION_PASS)).json() + print(schedule) + await ctx.send('\n'.join([f"{i['name']} {i['start']}-{i['end']}" for i in schedule['results'][0]['day_type']['blocks']])) + +@bot.command(name='roll_dice', help='Simulates rolling dice.') +async def roll(ctx, number_of_dice: int, number_of_sides: int): + dice = [ + str(random.choice(range(1, number_of_sides + 1))) + for _ in range(number_of_dice) + ] + await ctx.send(', '.join(dice)) + +@bot.command(name='info', help='Gets profile info for a user on Ion') +@commands.has_role(ADMIN_ROLE) +async def info(ctx, username): + info = requests.get(ION_API_URL+f'/profile/{username}', auth=requests.auth.HTTPBasicAuth(ION_USER, ION_PASS)).json() + print(schedule) + await ctx.send('\n'.join([f"{i}: {info[i]}" for i in info])) + +@bot.command(name='99', help='Responds with a random quote from Brooklyn 99') +async def nine_nine(ctx): + brooklyn_99_quotes = [ + 'I\'m the human form of the 💯 emoji.', + 'Bingpot!', + ( + 'Cool. Cool cool cool cool cool cool cool, ' + 'no doubt no doubt no doubt no doubt.' + ), + ] + + response = random.choice(brooklyn_99_quotes) + await ctx.send(response) + +@bot.event +async def on_command_error(ctx, error): + + if isinstance(error, commands.errors.CheckFailure): + await ctx.send('You don\'t have the correct role for this command. weeb.') +@bot.event +async def on_error(event, *args, **kwargs): + with open('err.log', 'a') as f: + if event == 'on_message': + f.write(f'Unhandled message: {args[0]}\n') + else: + f.write(f'Other error: {args[0]}\n') + +bot.run(TOKEN)