Example #1
0
 def send_notification(self, text):
     """Send unrequested message to other bot"""
     # Notify Discord bot of Mumble activity
     bot_message = BotMessage()
     bot_message.type = BotMessage.Type.ACTIVITY
     bot_message.direction = BotMessage.Direction.INFO
     bot_message.source = BotMessage.Source.MUMBLE
     bot_message.std.text = text
     if bot_message_str := commonbot.write_bot_message(bot_message):
         self.otherbot_comm_queue.put_nowait(bot_message_str)
Example #2
0
def main():
    """Program launcher"""
    options = handle_options()
    print("discomblebot start")
    discord_config, mumble_config = confbot.load_configuration(
        options.conf_file, options.environment)

    discobot_comm_queue = Queue()
    mumbot_comm_queue = Queue()
    if not options.debug_discord:
        dbp = Process(target=discobot.run, args=(
            discobot_comm_queue, mumbot_comm_queue, discord_config))
        dbp.start()
    if not options.debug_mumble:
        mbp = Process(target=mumbot.run, args=(
            mumbot_comm_queue, discobot_comm_queue, mumble_config))
        mbp.start()
    if options.debug_discord:
        discobot.run(discobot_comm_queue, mumbot_comm_queue, discord_config)
    if options.debug_mumble:
        mumbot.run(mumbot_comm_queue, discobot_comm_queue, mumble_config)

    if options.interactive:
        try:
            interactive_loop(discobot_comm_queue, mumbot_comm_queue)
        except KeyboardInterrupt:
            print("Terminating discomblebot")

        #Give bots a chance to exit gracefully
        bot_message = BotMessage()
        bot_message.type = BotMessage.Type.QUIT
        bot_message.direction = BotMessage.Direction.REQUEST
        bot_message.source = BotMessage.Source.CLI
        if bot_message_str := commonbot.write_bot_message(bot_message):
            discobot_comm_queue.put_nowait(bot_message_str)
            mumbot_comm_queue.put_nowait(bot_message_str)

        dbp.join(5)
        if dbp.is_alive():
            print("Force Discord bot exit")
            dbp.terminate()
        mbp.join(5)
        if mbp.is_alive():
            print("Force Mumble bot exit")
            mbp.terminate()
Example #3
0
async def on_voice_state_update(member, before, after):
    """Monitor Discord voice join/leave activity"""
    if member == client.user:
        return
    activity_str = None
    if before.channel is None and after.channel is not None:
        activity_str = "User %s enabled voice on the Discord server" % member.name
    elif before.channel is not None and after.channel is None:
        activity_str = "User %s disabled voice on the Discord server" % member.name
    if activity_str:
        # Notify Mumble bot of Discord activity
        bot_message = BotMessage()
        bot_message.type = BotMessage.Type.ACTIVITY
        bot_message.direction = BotMessage.Direction.INFO
        bot_message.source = BotMessage.Source.DISCORD
        bot_message.std.text = activity_str
        if bot_message_str := commonbot.write_bot_message(bot_message):
            otherbot_comm_queue.put_nowait(bot_message_str)
        # Also log activity in Discord
        await default_channel.send(activity_str)
Example #4
0
def interactive_loop(discobot_cmd_queue, mumbot_cmd_queue):
    """Interactive loop waiting for user input commands."""
    while True:
        #print("bleigh")
        try:
            cmd = input("Enter command:")
        # handle bad KeyboardInterrupt/input() interactions (https://stackoverflow.com/a/31131378)
        except EOFError:
            time.sleep(1)
        if cmd == "!quit":
            print("Quitting")
            break
        if cmd == "!status":
            bot_message = BotMessage()
            bot_message.type = BotMessage.Type.STATUS
            bot_message.direction = BotMessage.Direction.REQUEST
            bot_message.source = BotMessage.Source.CLI
            if bot_message_str := commonbot.write_bot_message(bot_message):
                discobot_cmd_queue.put_nowait(bot_message_str)
                mumbot_cmd_queue.put_nowait(bot_message_str)
        else:
            print("Unknown command %s" % cmd)
            print("Supported commands are: !quit, !status")
Example #5
0
async def invite(channel, sender, recipient, from_bot):
    """Invite mumble user to discord"""
    # Invites are channel-level, not guild-level, oddly enough
    channel_invite = await default_channel.create_invite(
        max_age=86400, max_uses=1, unique=True, reason="discomble")
    print(channel_invite)
    bot_message = BotMessage()
    bot_message.type = BotMessage.Type.INVITE
    if from_bot:
        bot_message.direction = BotMessage.Direction.RESPONSE
    else:
        bot_message.direction = BotMessage.Direction.INFO
    bot_message.source = BotMessage.Source.DISCORD
    bot_message.channel = channel
    bot_message.invite.sender = sender
    bot_message.invite.recipient = recipient
    bot_message.invite.url = channel_invite.url
    if bot_message_str := commonbot.write_bot_message(bot_message):
        otherbot_comm_queue.put_nowait(bot_message_str)
Example #6
0
 def status(self, channel=None):
     """Respond to status command"""
     #print(self.mumble.users)
     status_str = "%d users (%s) are connected on the Mumble server" % (
         self.mumble.users.count(), ", ".join(
             [user['name'] for _userid, user in self.mumble.users.items()]))
     print(status_str)
     bot_message = BotMessage()
     bot_message.type = BotMessage.Type.STATUS
     bot_message.direction = BotMessage.Direction.RESPONSE
     bot_message.source = BotMessage.Source.MUMBLE
     bot_message.std.text = status_str
     if channel:
         bot_message.channel = channel
     if bot_message_str := commonbot.write_bot_message(bot_message):
         self.otherbot_comm_queue.put(bot_message_str)
Example #7
0
async def status(channel=None):
    """Respond to status command"""
    voice_channels = [
        channel for channel in client.get_all_channels()
        if isinstance(channel, discord.VoiceChannel)]
    voice_members = [member.name for channel in voice_channels for member in channel.members]
    status_str = "%d users (%s) are connected on the Discord server" % (
        len(voice_members),
        ", ".join(voice_members))
    print(status_str)
    bot_message = BotMessage()
    bot_message.type = BotMessage.Type.STATUS
    bot_message.direction = BotMessage.Direction.RESPONSE
    bot_message.source = BotMessage.Source.DISCORD
    bot_message.std.text = status_str
    if channel:
        bot_message.channel = channel
    if bot_message_str := commonbot.write_bot_message(bot_message):
        otherbot_comm_queue.put_nowait(bot_message_str)
Example #8
0
async def on_message(message):
    """Handle chat user commands sent in Discord"""
    if message.author == client.user:
        return
    cmd = commonbot.parse_chat_message(message.content)
    if cmd is None:
        return
    if cmd == commonbot.HELLO_CMD:
        await message.channel.send("Hello %s !" % message.author)
    elif cmd == commonbot.VERSION_CMD:
        await message.channel.send("Current version: %s" % confbot.VERSION)
    elif cmd == commonbot.HELP_CMD:
        await message.channel.send(commonbot.get_chat_help_message())
    elif cmd == commonbot.STATUS_CMD:
        bot_message = BotMessage()
        bot_message.type = BotMessage.Type.STATUS
        bot_message.direction = BotMessage.Direction.REQUEST
        bot_message.source = BotMessage.Source.DISCORD
        bot_message.channel = "%d" % message.channel.id
        if bot_message_str := commonbot.write_bot_message(bot_message):
            otherbot_comm_queue.put_nowait(bot_message_str)
Example #9
0
 def loop(self):
     """Main loop of the mumble bot"""
     while discord_msg := self.comm_queue.get():
         if not self.mumble.is_alive():
             print("Mumble bot thread died, restarting")
             self.start_client()
         if bot_message := commonbot.read_bot_message(discord_msg):
             print(
                 "Mumble bot: message received with type %d direction %s source %d"
                 % (bot_message.type, bot_message.direction,
                    bot_message.source))
             if bot_message.type == bot_message.Type.QUIT:
                 print("Mumble bot stopping on command")
                 break
             if bot_message.type == bot_message.Type.STATUS:
                 if bot_message.direction == bot_message.Direction.REQUEST:
                     print("Status request from discord bot: %s" %
                           bot_message.std.text)
                     self.status(bot_message.channel)
                 else:
                     print("Status response from discord bot: %s" %
                           bot_message.std.text)
                     if bot_message.channel:
                         channel_id = int(bot_message.channel)
                         if channel_id in self.mumble.users:
                             output_channel = self.mumble.users[channel_id]
                         else:
                             output_channel = self.mumble.channels[
                                 channel_id]
                     else:
                         output_channel = self.mumble.channels[
                             self.mumble.users.myself['channel_id']]
                     if output_channel:
                         output_channel.send_text_message(
                             bot_message.std.text)
             elif bot_message.type == bot_message.Type.ACTIVITY:
                 print("Notification received from discord bot: %s" %
                       bot_message.std.text)
                 my_channel_id = self.mumble.users.myself['channel_id']
                 self.mumble.channels[my_channel_id].send_text_message(
                     bot_message.std.text)
             elif bot_message.type == bot_message.Type.INVITE:
                 if bot_message.direction in [
                         bot_message.Direction.INFO,
                         bot_message.Direction.RESPONSE
                 ]:
                     sender_name = bot_message.invite.sender
                     recipient_name = bot_message.invite.recipient
                     invite_url = bot_message.invite.url
                     print("Mumble bot receiving invite %s from %s for %s" %
                           (invite_url, sender_name, recipient_name))
                     usersdict = {
                         user['name']: userid
                         for userid, user in self.mumble.users.items()
                     }
                     if recipient_name in usersdict:
                         # Send PM to user with invite link
                         self.mumble.users[
                             usersdict[recipient_name]].send_text_message(
                                 "%s has invited you to a Discord server: <a href=\"%s\">%s</a>"
                                 % (sender_name, invite_url, invite_url))
                         invite_successful = True
                     else:
                         invite_successful = False
                     if bot_message.direction == bot_message.Direction.RESPONSE:
                         if invite_successful:
                             success_message = "%s has been invited to Discord." % (
                                 recipient_name)
                             # Send OK message to mumble sender
                             if sender_name in usersdict:
                                 self.mumble.users[usersdict[
                                     sender_name]].send_text_message(
                                         success_message)
                     else:
                         new_bot_message = BotMessage()
                         new_bot_message.type = BotMessage.Type.ACTIVITY
                         new_bot_message.direction = BotMessage.Direction.INFO
                         new_bot_message.source = BotMessage.Source.MUMBLE
                         new_bot_message.channel = bot_message.channel
                         # TODO improve invite response to discord text
                         if invite_successful:
                             # Send OK message to Discord sender
                             new_bot_message.std.text = "Invite OK"
                         else:
                             # Send error message to discord sender
                             new_bot_message.std.text = "Invite KO"
                         if bot_message_str := commonbot.write_bot_message(
                                 new_bot_message):
                             self.otherbot_comm_queue.put_nowait(
                                 bot_message_str)
Example #10
0
 else:
     print("Mumble bot cannot identify output channel")
     return
 if (cmd := commonbot.parse_chat_message(message.message)) is None:
     return
 #print("Mumble bot CMD: %s" % cmd)
 if cmd == commonbot.HELLO_CMD:
     output_channel.send_text_message(
         "Hello %s !" % self.mumble.users[message.actor]['name'])
 elif cmd == commonbot.VERSION_CMD:
     output_channel.send_text_message("Current version: %s" %
                                      confbot.VERSION)
 elif cmd == commonbot.HELP_CMD:
     output_channel.send_text_message(commonbot.get_chat_help_message())
 elif cmd == commonbot.STATUS_CMD:
     bot_message = BotMessage()
     bot_message.type = BotMessage.Type.STATUS
     bot_message.direction = BotMessage.Direction.REQUEST
     bot_message.source = BotMessage.Source.MUMBLE
     if message.channel_id:
         bot_message.channel = "%d" % message.channel_id[0]
     elif message.session:
         bot_message.channel = "%d" % message.actor
     if bot_message_str := commonbot.write_bot_message(bot_message):
         self.otherbot_comm_queue.put_nowait(bot_message_str)
 elif cmd == commonbot.INVITE_CMD:
     sender_name = self.mumble.users[message.actor]['name']
     recipient_name = commonbot.get_chat_cmd_param(message.message)
     print("Mumble bot requesting invite for %s" % recipient_name)
     if recipient_name in [
             user['name']