|
@@ -0,0 +1,109 @@
|
|
|
+#!/usr/bin/env python3
|
|
|
+
|
|
|
+import discord
|
|
|
+import random
|
|
|
+import re
|
|
|
+
|
|
|
+# TODO: don't keep this token in the code itself!
|
|
|
+TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
|
|
|
+NONLETTER = re.compile('[^A-Za-z0-9]')
|
|
|
+
|
|
|
+client = discord.Client()
|
|
|
+
|
|
|
+def occasionally() -> bool:
|
|
|
+ '''
|
|
|
+ returns True one in every twenty times
|
|
|
+ '''
|
|
|
+ return random.randint(0, 20) == 0
|
|
|
+
|
|
|
+class Msg:
|
|
|
+ '''
|
|
|
+ Just a nice wrapper class to wrap messages in, which makes it easier
|
|
|
+ to write high-level response functions
|
|
|
+ '''
|
|
|
+ def __init__(self, msg: str):
|
|
|
+ self.msg = msg
|
|
|
+ self.raw = NONLETTER.split(msg.content.lower())
|
|
|
+ self.words = set(self.raw)
|
|
|
+
|
|
|
+ def __contains__(self, substr: str):
|
|
|
+ '''
|
|
|
+ Check to see if the message contains this substring or sequence of
|
|
|
+ substrings (if it's a list)
|
|
|
+ '''
|
|
|
+ if type(substr) is str:
|
|
|
+ return substr in self.words
|
|
|
+ elif type(substr) is list:
|
|
|
+ find_len = len(substr)
|
|
|
+ for x in range(len(self.raw)):
|
|
|
+ if self.raw[x:x+find_len] == substr:
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+ async def respond_with_image(self, image_path: str, target=None):
|
|
|
+ '''
|
|
|
+ Respond to a message with an image present in our image path
|
|
|
+ '''
|
|
|
+ with open('./imgs/{}'.format(image_path), mode='rb') as f:
|
|
|
+ f = discord.File(f)
|
|
|
+ if target is None:
|
|
|
+ target = self.msg.author.mention
|
|
|
+ await self.msg.channel.send(target, files=[f])
|
|
|
+
|
|
|
+ async def respond(self, text):
|
|
|
+ '''
|
|
|
+ Respond to a message with a simple piece of text
|
|
|
+ '''
|
|
|
+ await self.msg.channel.send(text)
|
|
|
+
|
|
|
+@client.event
|
|
|
+async def on_message(message):
|
|
|
+ # we do not want the bot to reply to itself
|
|
|
+ if message.author == client.user:
|
|
|
+ return
|
|
|
+
|
|
|
+ # wrap the message in our Msg wrapper
|
|
|
+ msg = Msg(message)
|
|
|
+
|
|
|
+ # TODO: turn this into a data-driven table (and maybe put a web
|
|
|
+ # frontend here?) instead of just having a bunch of conditions
|
|
|
+ if 'oof' in msg and occasionally():
|
|
|
+ await msg.respond_with_image('cringe-compilation.jpg')
|
|
|
+
|
|
|
+ if 'sandwich' in msg and occasionally():
|
|
|
+ await msg.respond_with_image('snadwich.jpg')
|
|
|
+
|
|
|
+ if 'anime' in msg and occasionally():
|
|
|
+ response = random.choice([
|
|
|
+ '"anime" lmao',
|
|
|
+ 'anime? you mean pervert cartoons?',
|
|
|
+ ]);
|
|
|
+ await msg.respond(response)
|
|
|
+
|
|
|
+ # song lyric section
|
|
|
+ if ['almost','heaven'] in msg:
|
|
|
+ await msg.respond('west virginia')
|
|
|
+
|
|
|
+ if ['blue','ridge','mountains'] in msg:
|
|
|
+ await msg.respond('shenandoah river')
|
|
|
+
|
|
|
+ if ['my','life','into','pieces'] in msg:
|
|
|
+ await msg.respond('THIS IS MY LAST RESORT')
|
|
|
+
|
|
|
+@client.event
|
|
|
+async def on_reaction_add(reaction, user):
|
|
|
+ if reaction.emoji == '🐱':
|
|
|
+ msg = reaction.message
|
|
|
+ modified_message = msg.content.lower().replace('l', 'w').replace('r', 'w')
|
|
|
+ face = random.choice(['OwO', 'UwU', '^w^', 'owo', ':3c', ':3cccc'])
|
|
|
+ await msg.channel.send('{}: {} {}'.format(msg.author.mention, modified_message, face))
|
|
|
+ else:
|
|
|
+ print(reaction.emoji)
|
|
|
+
|
|
|
+@client.event
|
|
|
+async def on_ready():
|
|
|
+ c_name, c_id = client.user.name, client.user.id
|
|
|
+ print('Logged in as {} ({})'.format(c_name, c_id))
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ client.run(TOKEN)
|