This commit is contained in:
git-bruh 2021-01-27 17:48:09 +05:30
parent 4eb73aa87f
commit c742a0bd55
No known key found for this signature in database
GPG key ID: E1475C50075ADCE6
3 changed files with 43 additions and 56 deletions

View file

@ -28,7 +28,7 @@ A simple non-puppeting bridge between Matrix and Discord written in Python.
* Normal Discord bot functionality like commands can be added to the bot via [cogs](https://discordpy.readthedocs.io/en/latest/ext/commands/cogs.html), example [here](https://gist.github.com/EvieePy/d78c061a4798ae81be9825468fe146be). * Normal Discord bot functionality like commands can be added to the bot via [cogs](https://discordpy.readthedocs.io/en/latest/ext/commands/cogs.html), example [here](https://gist.github.com/EvieePy/d78c061a4798ae81be9825468fe146be).
* Apply `use_client_emojis.patch` to make the Discord bot use emojis from all it's servers. * Replace `guild.emojis` with `self.discord_client.emojis` (`Callbacks()`, `process_message()`) to make the Discord bot use emojis from ALL it's guilds.
NOTE: [Privileged Intents](https://discordpy.readthedocs.io/en/latest/intents.html#privileged-intents) must be enabled for your Discord bot. NOTE: [Privileged Intents](https://discordpy.readthedocs.io/en/latest/intents.html#privileged-intents) must be enabled for your Discord bot.

63
main.py
View file

@ -1,7 +1,9 @@
import asyncio
import json import json
import logging import logging
import os import os
import re import re
import traceback
import sys import sys
import uuid import uuid
import aiofiles import aiofiles
@ -36,17 +38,22 @@ def config_gen(config_file):
config = config_gen("config.json") config = config_gen("config.json")
message_store, channel_store = {}, {} message_store = {}
class MatrixClient(nio.AsyncClient): class MatrixClient(nio.AsyncClient):
def __init__(self, *args, **kwargs): def __init__(self, discord_client, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.logger = logging.getLogger("matrix_logger") self.logger = logging.getLogger("matrix_logger")
self.discord_client = discord_client
self.ready = asyncio.Event()
self.uploaded_emotes = {} self.uploaded_emotes = {}
async def start(self, discord_client): async def start(self):
password = config["password"] password = config["password"]
timeout = 30000 timeout = 30000
@ -56,8 +63,9 @@ class MatrixClient(nio.AsyncClient):
await self.sync(timeout) await self.sync(timeout)
# Set up event callbacks after syncing once to ignore old messages. # Set up event callbacks after syncing once to ignore old messages.
callbacks = Callbacks(self) callbacks = Callbacks(self.discord_client, self)
self.logger.info("Adding callbacks.")
self.add_event_callback( self.add_event_callback(
callbacks.message_callback, callbacks.message_callback,
(nio.RoomMessageText, nio.RoomMessageMedia, (nio.RoomMessageText, nio.RoomMessageMedia,
@ -72,8 +80,10 @@ class MatrixClient(nio.AsyncClient):
callbacks.typing_callback, nio.EphemeralEvent callbacks.typing_callback, nio.EphemeralEvent
) )
# Wait for Discord client... await self.discord_client.ready.wait()
await discord_client.wait_until_ready() self.ready.set()
self.logger.info("Clients ready.")
self.logger.info("Syncing forever.") self.logger.info("Syncing forever.")
await self.sync_forever(timeout=timeout) await self.sync_forever(timeout=timeout)
@ -199,7 +209,7 @@ height=\"32\" src=\"{emote_}\" data-mx-emoticon />"""
async def webhook_send(self, author, avatar, message, async def webhook_send(self, author, avatar, message,
event_id, channel_id, embed=None): event_id, channel_id, embed=None):
channel = channel_store[channel_id] channel = self.discord_client.channel_store[channel_id]
hook_name = "matrix_bridge" hook_name = "matrix_bridge"
@ -228,16 +238,20 @@ class DiscordClient(discord.ext.commands.Bot):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.channel_store = {}
self.ready = asyncio.Event()
self.add_cogs()
self.matrix_client = MatrixClient( self.matrix_client = MatrixClient(
config["homeserver"], config["username"] self, config["homeserver"], config["username"]
) )
self.bg_task = self.loop.create_task( self.bg_task = self.loop.create_task(
self.log_exceptions(self.matrix_client) self.log_exceptions(self.matrix_client)
) )
self.add_cogs()
def add_cogs(self): def add_cogs(self):
cogs_dir = "./cogs" cogs_dir = "./cogs"
@ -249,28 +263,34 @@ class DiscordClient(discord.ext.commands.Bot):
cog = f"cogs.{cog[:-3]}" cog = f"cogs.{cog[:-3]}"
self.load_extension(cog) self.load_extension(cog)
def to_return(self, channel_id, user): async def to_return(self, channel_id, user):
await self.matrix_client.ready.wait()
if user.discriminator == "0000" \ if user.discriminator == "0000" \
or str(channel_id) not in config["bridge"].keys(): or str(channel_id) not in config["bridge"].keys():
return True return True
async def log_exceptions(self, matrix_client): async def log_exceptions(self, matrix_client):
try: try:
return await matrix_client.start(self) return await matrix_client.start()
except Exception as e: except Exception:
matrix_client.logger.warning(f"Unknown exception occurred: {e}") matrix_client.logger.warning(
f"Unknown exception occurred\n{traceback.format_exc()}"
)
await matrix_client.close() await matrix_client.close()
async def on_ready(self): async def on_ready(self):
for channel in config["bridge"].keys(): for channel in config["bridge"].keys():
channel_store[channel] = self.get_channel(int(channel)) self.channel_store[channel] = self.get_channel(int(channel))
self.ready.set()
async def on_message(self, message): async def on_message(self, message):
# Process other stuff like cogs before ignoring the message. # Process other stuff like cogs before ignoring the message.
await self.process_commands(message) await self.process_commands(message)
if self.to_return(message.channel.id, message.author): if await self.to_return(message.channel.id, message.author):
return return
content = await self.process_message(message) content = await self.process_message(message)
@ -283,7 +303,7 @@ class DiscordClient(discord.ext.commands.Bot):
message_store[message.id] = matrix_message message_store[message.id] = matrix_message
async def on_message_edit(self, before, after): async def on_message_edit(self, before, after):
if self.to_return(after.channel.id, after.author): if await self.to_return(after.channel.id, after.author):
return return
content = await self.process_message(after) content = await self.process_message(after)
@ -303,7 +323,7 @@ class DiscordClient(discord.ext.commands.Bot):
) )
async def on_typing(self, channel, user, when): async def on_typing(self, channel, user, when):
if self.to_return(channel.id, user) or user == self.user: if await self.to_return(channel.id, user) or user == self.user:
return return
# Send typing event # Send typing event
@ -351,7 +371,8 @@ class DiscordClient(discord.ext.commands.Bot):
class Callbacks(object): class Callbacks(object):
def __init__(self, matrix_client): def __init__(self, discord_client, matrix_client):
self.discord_client = discord_client
self.matrix_client = matrix_client self.matrix_client = matrix_client
def get_channel(self, room): def get_channel(self, room):
@ -484,7 +505,7 @@ class Callbacks(object):
channel_id = self.get_channel(room) channel_id = self.get_channel(room)
# Send typing event. # Send typing event.
async with channel_store[channel_id].typing(): async with self.discord_client.channel_store[channel_id].typing():
return return
async def process_message(self, message, channel_id): async def process_message(self, message, channel_id):
@ -492,7 +513,7 @@ class Callbacks(object):
emotes = re.findall(r":(\w*):", message) emotes = re.findall(r":(\w*):", message)
# Get the guild from channel ID. # Get the guild from channel ID.
guild = channel_store[channel_id].guild guild = self.discord_client.channel_store[channel_id].guild
added_emotes = [] added_emotes = []
for emote in emotes: for emote in emotes:

View file

@ -1,34 +0,0 @@
diff --git a/main.py b/main.py
index 21adf31..31cdd28 100644
--- a/main.py
+++ b/main.py
@@ -56,7 +56,7 @@ class MatrixClient(nio.AsyncClient):
await self.sync(timeout)
# Set up event callbacks after syncing once to ignore old messages.
- callbacks = Callbacks(self)
+ callbacks = Callbacks(self, discord_client)
self.add_event_callback(
callbacks.message_callback,
@@ -351,8 +351,9 @@ class DiscordClient(discord.ext.commands.Bot):
class Callbacks(object):
- def __init__(self, matrix_client):
+ def __init__(self, matrix_client, discord_client):
self.matrix_client = matrix_client
+ self.discord_client = discord_client
def get_channel(self, room):
channel_id = next(
@@ -500,7 +501,9 @@ class Callbacks(object):
# :emote: becomes <:emote:emote_id>
if emote not in added_emotes:
added_emotes.append(emote)
- emote_ = discord.utils.get(guild.emojis, name=emote)
+ emote_ = discord.utils.get(
+ self.discord_client.emojis, name=emote
+ )
if emote_:
message = message.replace(f":{emote}:", str(emote_))