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)
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()
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)
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")
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)
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)
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)
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)
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)
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']