""" Copyright 2018 Alex Taber ("astronautlevel") Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ from matrix_client.client import MatrixClient import discord import requests import re from config import * matrix_client = MatrixClient(matrix_homeserver) token = matrix_client.login(matrix_username, matrix_password) discord_client = discord.Client() matrix_room = matrix_client.join_room(matrix_room_id) matrix_file_types = ('m.file', 'm.image', 'm.video', 'm.audio') message_id_cache = {} unmatched_messages_cache = {} message_delete_queue = [] def prepare_matrix_content(message): reg = re.match(r"^$", message.content) if reg: try: return emoji_urls[message.content] except: pass attachments = "\n".join([x.url for x in message.attachments]) content = message.clean_content + ("\n" + attachments if attachments != "" else "") content = re.sub(r"", r"\g<1>", content) return content guild = None channel = None emojis = {} emoji_urls = {} @discord_client.event async def on_ready(): global guild global emojis global webhook global channel channel = discord_client.get_channel(discord_channel) guild = channel.guild for emoji in guild.emojis: if not emoji.animated: emojis[":{}:".format(emoji.name)] = "<:{}:{}>".format(emoji.name, emoji.id) emoji_urls["<:{}:{}>".format(emoji.name, emoji.id)] = emoji.url + "?size=32" else: emojis[":{}:".format(emoji.name)] = "".format(emoji.name, emoji.id) emoji_urls["".format(emoji.name, emoji.id)] = emoji.url + "?size=32" @discord_client.event async def on_message(message): for message_id in message_delete_queue: message_delete_queue.remove(message_id) message = await channel.get_message(message_id) await message.delete() if message.author.name in unmatched_messages_cache.keys(): message_id_cache[unmatched_messages_cache[message.author.name]] = message.id del unmatched_messages_cache[message.author.name] if message.author.discriminator == "0000" or message.channel.id != discord_channel: return username = message.author.name[:1] + "\u200B" + message.author.name[1:] + "#" + message.author.discriminator content = prepare_matrix_content(message) matrix_message_id = matrix_room.send_text("<{}> {}".format(username, content))['event_id'] message_id_cache[message.id] = matrix_message_id @discord_client.event async def on_message_edit(before, after): if after.author.discriminator == "0000" or after.channel.id != discord_channel: return if after.content == before.content: return after.attachments = [] username = after.author.name[:1] + "\u200B" + after.author.name[1:] + "#" + after.author.discriminator content = prepare_matrix_content(after) matrix_room.redact_message(message_id_cache[before.id], reason="Message Edited") message_id_cache[after.id] = matrix_room.send_text("<{}> {} (edited)".format(username, content))['event_id'] @discord_client.event async def on_raw_message_delete(paylod): if payload.message_id in message_id_cache.keys(): matrix_room.redact_message(message_id_cache[paylod.message_id], reason="Message Deleted") def send_webhook(username, avatar_url, content, matrix_id): unmatched_messages_cache[username] = matrix_id; payload = {} payload['content'] = content payload['avatar_url'] = avatar_url payload['username'] = username for tries in range(5): r = requests.post(webhook_url, data = payload) if r.ok: return else: print(r.status_code) def prepare_discord_content(content): content = content.replace("@everyone", "@\u200Beveryone") content = content.replace("@here", "@\u200Bhere") content = re.sub("", "~~", content) mentions = re.findall("(^|\s)(@(\w*))", content) for mention in mentions: member = guild.get_member_named(mention[2]) if not member: continue content = content.replace(mention[1], member.mention) for emoji_name, emoji_id in emojis.items(): if emoji_name in content: content = content.replace(emoji_name, emoji_id) return content def on_matrix_message(room, event): user = matrix_client.get_user(event['sender']) if event['type'] == "m.room.message" and not user.user_id == matrix_user_id: if event['content']['msgtype'] == "m.text": username = "{}{}".format(discord_prefix, user.get_display_name()) avatar = user.get_avatar_url() content = prepare_discord_content(event['content']['body']) send_webhook(username, avatar, content, event['event_id']) if event['content']['msgtype'] in matrix_file_types: username = "{}{}".format(discord_prefix, user.get_display_name()) avatar = user.get_avatar_url() content = matrix_homeserver + "/_matrix/media/v1/download/" + event['content']['url'][6:] send_webhook(username, avatar, content, event['event_id']) if event['type'] == "m.room.redaction" and not user.user_id == matrix_user_id: try: message_delete_queue.append(message_id_cache[event['redacts']]) except KeyError: pass matrix_room.add_listener(on_matrix_message) matrix_client.start_listener_thread() discord_client.run(discord_token)