Nessuna descrizione

app.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. """
  2. Copyright 2018 Alex Taber ("astronautlevel")
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. """
  13. from matrix_client.client import MatrixClient
  14. import discord
  15. import requests
  16. import re
  17. from config import *
  18. matrix_client = MatrixClient(matrix_homeserver)
  19. token = matrix_client.login(matrix_username, matrix_password)
  20. discord_client = discord.Client()
  21. matrix_room = matrix_client.join_room(matrix_room_id)
  22. matrix_file_types = ('m.file', 'm.image', 'm.video', 'm.audio')
  23. message_id_cache = {}
  24. unmatched_messages_cache = {}
  25. message_delete_queue = []
  26. def prepare_matrix_content(message):
  27. reg = re.match(r"^<a?:\w+:\d*>$", message.content)
  28. if reg:
  29. try:
  30. return emoji_urls[message.content]
  31. except:
  32. pass
  33. attachments = "\n".join([x.url for x in message.attachments])
  34. content = message.clean_content + ("\n" + attachments if attachments != "" else "")
  35. content = re.sub(r"<a?(:\w+:)\d*>", r"\g<1>", content)
  36. return content
  37. guild = None
  38. channel = None
  39. emojis = {}
  40. emoji_urls = {}
  41. @discord_client.event
  42. async def on_ready():
  43. global guild
  44. global emojis
  45. global webhook
  46. global channel
  47. channel = discord_client.get_channel(discord_channel)
  48. guild = channel.guild
  49. for emoji in guild.emojis:
  50. if not emoji.animated:
  51. emojis[":{}:".format(emoji.name)] = "<:{}:{}>".format(emoji.name, emoji.id)
  52. emoji_urls["<:{}:{}>".format(emoji.name, emoji.id)] = emoji.url + "?size=32"
  53. else:
  54. emojis[":{}:".format(emoji.name)] = "<a:{}:{}>".format(emoji.name, emoji.id)
  55. emoji_urls["<a:{}:{}>".format(emoji.name, emoji.id)] = emoji.url + "?size=32"
  56. @discord_client.event
  57. async def on_message(message):
  58. for message_id in message_delete_queue:
  59. message_delete_queue.remove(message_id)
  60. message = await channel.get_message(message_id)
  61. await message.delete()
  62. if message.author.name in unmatched_messages_cache.keys():
  63. message_id_cache[unmatched_messages_cache[message.author.name]] = message.id
  64. del unmatched_messages_cache[message.author.name]
  65. if message.author.discriminator == "0000" or message.channel.id != discord_channel: return
  66. username = message.author.name[:1] + "\u200B" + message.author.name[1:] + "#" + message.author.discriminator
  67. content = prepare_matrix_content(message)
  68. matrix_message_id = matrix_room.send_text("<{}> {}".format(username, content))['event_id']
  69. message_id_cache[message.id] = matrix_message_id
  70. @discord_client.event
  71. async def on_message_edit(before, after):
  72. if after.author.discriminator == "0000" or after.channel.id != discord_channel: return
  73. if after.content == before.content: return
  74. after.attachments = []
  75. username = after.author.name[:1] + "\u200B" + after.author.name[1:] + "#" + after.author.discriminator
  76. content = prepare_matrix_content(after)
  77. matrix_room.redact_message(message_id_cache[before.id], reason="Message Edited")
  78. message_id_cache[after.id] = matrix_room.send_text("<{}> {} (edited)".format(username, content))['event_id']
  79. @discord_client.event
  80. async def on_raw_message_delete(paylod):
  81. if payload.message_id in message_id_cache.keys():
  82. matrix_room.redact_message(message_id_cache[paylod.message_id], reason="Message Deleted")
  83. def send_webhook(username, avatar_url, content, matrix_id):
  84. unmatched_messages_cache[username] = matrix_id;
  85. payload = {}
  86. payload['content'] = content
  87. payload['avatar_url'] = avatar_url
  88. payload['username'] = username
  89. for tries in range(5):
  90. r = requests.post(webhook_url, data = payload)
  91. if r.ok:
  92. return
  93. else:
  94. print(r.status_code)
  95. def prepare_discord_content(content):
  96. content = content.replace("@everyone", "@\u200Beveryone")
  97. content = content.replace("@here", "@\u200Bhere")
  98. content = re.sub("</?del>", "~~", content)
  99. mentions = re.findall("(^|\s)(@(\w*))", content)
  100. for mention in mentions:
  101. member = guild.get_member_named(mention[2])
  102. if not member: continue
  103. content = content.replace(mention[1], member.mention)
  104. for emoji_name, emoji_id in emojis.items():
  105. if emoji_name in content:
  106. content = content.replace(emoji_name, emoji_id)
  107. return content
  108. def on_matrix_message(room, event):
  109. user = matrix_client.get_user(event['sender'])
  110. if event['type'] == "m.room.message" and not user.user_id == matrix_user_id:
  111. if event['content']['msgtype'] == "m.text":
  112. username = "{}{}".format(discord_prefix, user.get_display_name())
  113. avatar = user.get_avatar_url()
  114. content = prepare_discord_content(event['content']['body'])
  115. send_webhook(username, avatar, content, event['event_id'])
  116. if event['content']['msgtype'] in matrix_file_types:
  117. username = "{}{}".format(discord_prefix, user.get_display_name())
  118. avatar = user.get_avatar_url()
  119. content = matrix_homeserver + "/_matrix/media/v1/download/" + event['content']['url'][6:]
  120. send_webhook(username, avatar, content, event['event_id'])
  121. if event['type'] == "m.room.redaction" and not user.user_id == matrix_user_id:
  122. try:
  123. message_delete_queue.append(message_id_cache[event['redacts']])
  124. except KeyError:
  125. pass
  126. matrix_room.add_listener(on_matrix_message)
  127. matrix_client.start_listener_thread()
  128. discord_client.run(discord_token)