Browse Source

Merge branch 'deployment/discord' of kirkleon/rollbot3 into master

kirkleon 6 years ago
parent
commit
e5abf147e7
8 changed files with 101 additions and 20 deletions
  1. 2 2
      README.md
  2. 2 1
      config/secrets.toml.template
  3. 5 3
      src/app.py
  4. 16 0
      src/command_system.py
  5. 1 1
      src/config.py
  6. 68 0
      src/discord_bot.py
  7. 6 12
      src/rollbot.py
  8. 1 1
      src/util.py

+ 2 - 2
README.md

@@ -44,14 +44,14 @@ Open the new `secrets.toml` file in your preferred editor, and then navigate to
 [Bots](https://dev.groupme.com/bots) page. Then, on the bots page, create a new bot. For this
 bot's group, select the new chat you made above. Name can be whatever you like, and you can
 leave the other fields blank. Click submit, and retrieve your `Bot ID` and `Group ID` from the
-bots page. Put these in your `secrets.toml` under the `bots` section, with your `Group ID`
+bots page. Put these in your `secrets.toml` under the `groupme_bots` section, with your `Group ID`
 serving as the key and the `Bot ID` serving as the value (which must be in quotes).
 
 For example, if your bot ID is `456`, and your group ID is `789`, your `secrets.toml` needs to
 start with the following
 
 ```toml
-[bots]
+[groupme_bots]
 789 = "456"
 ```
 

+ 2 - 1
config/secrets.toml.template

@@ -1,6 +1,7 @@
 imgur_client_id = "YOUR-CLIENT-ID"
+discord_token = "YOUR-DISCORD-TOKEN"
 
-[bots]
+[groupme_bots]
 your_chat = "BOT-TOKEN"
 
 [auths]

+ 5 - 3
src/app.py

@@ -8,7 +8,7 @@ import db
 from config import BOTS_LOOKUP, get_config, get_secret
 from command_system import RollbotMessage, RollbotPlugin
 from rollbot import Rollbot
-from util import post_message, find_all_subclasses
+from util import post_groupme_message, find_all_subclasses
 import plugins
 
 GLOBAL_ADMINS = get_secret("auths.global")
@@ -37,9 +37,8 @@ rollbot = Rollbot(
     plugin_classes=find_all_subclasses(RollbotPlugin),
     aliases=get_config("aliases"),
     responses=get_config("responses"),
-    lookup=BOTS_LOOKUP,
     sleep_time=float(get_config("sleep_time")),
-    callback=post_message,
+    callback=lambda msg, group_id: post_groupme_message(msg, BOTS_LOOKUP[group_id]),
     session_factory=db.session_scope
 )
 app.logger.info("Initializing database tables")
@@ -63,6 +62,9 @@ def teamspeak():
 def execute():
     json = request.get_json()
     msg = RollbotMessage.from_groupme(json, global_admins=GLOBAL_ADMINS, group_admins=GROUP_ADMINS)
+    if msg.group_id in BOTS_LOOKUP:
+        self.logger.warning(f"Received message from unknown group ID {msg.group_id}")
+        return "", 400
     t = Thread(target=lambda: rollbot.handle_command(msg))
     t.start()
     return "", 204

+ 16 - 0
src/command_system.py

@@ -54,6 +54,22 @@ class RollbotMessage:
                 sender_id in group_admins[group_id])
         )
 
+    @staticmethod
+    def from_discord(msg, global_admins=(), group_admins={}):
+        sender_id = str(msg.author.id)
+        group_id = str(msg.channel.id)
+        return RollbotMessage(
+            "DISCORD",
+            msg.author.name,
+            sender_id,
+            group_id,
+            msg.id,
+            msg.content.strip(),
+            sender_id in global_admins or (
+                group_id in group_admins and
+                sender_id in group_admins[group_id])
+        )
+
     def args(self, normalize=True):
         arg, rest = pop_arg(self.raw_args)
         while arg is not None:

+ 1 - 1
src/config.py

@@ -26,5 +26,5 @@ def get_secret(key):
     return c
 
 
-BOTS_LOOKUP = get_secret("bots")
+BOTS_LOOKUP = get_secret("groupme_bots")
 DB_FILE = os.path.abspath(get_config("database"))

+ 68 - 0
src/discord_bot.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+import logging
+from logging.config import dictConfig
+import atexit
+
+import discord
+import discord.utils
+
+import db
+from util import find_all_subclasses
+from config import get_config, get_secret
+from rollbot import Rollbot
+from command_system import RollbotMessage, RollbotPlugin
+import plugins
+
+dictConfig({
+    'version': 1,
+    'disable_existing_loggers': False,
+    'formatters': {
+        'default': {'format': '%(asctime)s - %(levelname)s - %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S'}
+    },
+    'handlers': {
+        'console': {
+            'level': 'INFO',
+            'formatter': 'default',
+            'class': 'logging.StreamHandler',
+            'stream': 'ext://sys.stdout',
+        },
+    },
+    'loggers': {
+        '': {
+            'handlers': ['console'],
+            'level': 'INFO',
+            'propagate': True
+        },
+    }
+})
+
+client = discord.Client()
+
+msg_queue = []
+
+rollbot = Rollbot(
+    logger=logging,
+    plugin_classes=find_all_subclasses(RollbotPlugin),
+    aliases=get_config("aliases"),
+    responses=get_config("responses"),
+    callback=lambda msg, channel_id: msg_queue.append((msg, discord.utils.get(client.get_all_channels(), id=int(channel_id)))),
+    session_factory=db.session_scope
+)
+rollbot.logger.info("Initializing database tables")
+db.init_db()
+rollbot.logger.info("Finished initializing database")
+rollbot.start_plugins()
+atexit.register(rollbot.shutdown_plugins)
+
+
+@client.event
+async def on_message(message):
+    msg = RollbotMessage.from_discord(message) # TODO admins
+    rollbot.handle_command(msg)
+    while len(msg_queue) > 0:
+        content, channel = msg_queue.pop()
+        await channel.send(content)
+
+
+if __name__ == "__main__":
+    client.run(get_secret("discord_token"))

+ 6 - 12
src/rollbot.py

@@ -12,10 +12,10 @@ def lift_response(call, response):
 
 
 class Rollbot:
-    def __init__(self, logger=logging.getLogger(__name__), plugin_classes={}, aliases={}, responses={}, lookup={}, sleep_time=0.0, session_factory=None, callback=None):
+    def __init__(self, logger=logging.getLogger(__name__), plugin_classes={}, aliases={}, responses={}, sleep_time=0.0, session_factory=None, callback=None):
         self.logger = logger
         self.session_factory = session_factory or (lambda: None)
-        self.callback = callback or (lambda txt, gid: self.logger.info(f"Responding to {gid} with {txt}"))
+        self.post_callback = callback or (lambda txt, gid: self.logger.info(f"Responding to {gid} with {txt}"))
         self.commands = {}
         self.to_start = set()
         self.to_stop = set()
@@ -52,7 +52,6 @@ class Rollbot:
             self.commands[alias] = self.commands[cmd]
         self.logger.info(f"Finished loading aliases, {len(self.commands)} total commands + aliases available")
 
-        self.bot_lookup = lookup
         self.sleep_time = sleep_time
 
     def start_plugins(self):
@@ -94,10 +93,6 @@ class Rollbot:
             self.logger.debug("Ignoring non-command message")
             return
 
-        if message.group_id not in self.bot_lookup:
-            self.logger.warning(f"Received message from unknown group ID {message.group_id}")
-            return
-
         self.logger.info(f"Handling message {message.message_id}")
         t = time.time()
         try:
@@ -117,18 +112,17 @@ class Rollbot:
             self.logger.info(f"Sleeping for {sleep:.3f}s before responding")
             time.sleep(sleep)
 
-        bot_id = self.bot_lookup[message.group_id]
         if response.is_success:
             if response.txt is not None:
-                self.callback(response.txt, bot_id)
+                self.post_callback(response.txt, message.group_id)
             if response.img is not None:
-                self.callback(response.img, bot_id)
+                self.post_callback(response.img, message.group_id)
         else:
-            self.callback(response.failure_msg, bot_id)
+            self.post_callback(response.failure_msg, message.group_id)
             self.logger.warning(f"Failed command response: {response}")
 
         t = time.time() - t
         self.logger.info(f"Exiting command thread for {message.message_id} after {t:.3f}s")
 
     def manually_post_message(self, message_text, group_id):
-        self.callback(message_text, self.bot_lookup[group_id])
+        self.post_callback(message_text, group_id)

+ 1 - 1
src/util.py

@@ -5,7 +5,7 @@ import requests
 from requests.exceptions import ConnectionError
 
 
-def post_message(msg, bot_id):
+def post_groupme_message(msg, bot_id):
     requests.post(
         "https://api.groupme.com/v3/bots/post",
         json={