123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- """
- 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"^<a?:\w+:(\d+)>$", message.content)
-
- if reg:
- return "https://cdn.discordapp.com/emojis/{}.png?size=32".format(reg.group(1))
-
- attachments = "\n".join([x.url for x in message.attachments])
- content = message.clean_content + ("\n" + attachments if attachments != "" else "")
- content = re.sub(r"<a?(:\w+:)\d*>", r"\g<1>", content)
- return content
-
- guild = None
- channel = None
- emojis = {}
-
- @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)
- else:
- emojis[":{}:".format(emoji.name)] = "<a:{}:{}>".format(emoji.name, emoji.id)
-
- @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("</?del>", "~~", 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)
|