mirror of
https://github.com/ChronosX88/mastodon-bridge-bot.git
synced 2024-11-25 23:22:18 +00:00
Implement configurable repost routing from TG to Mastodon
This commit is contained in:
parent
a6bc05844b
commit
27b0d78116
64
bridge.py
64
bridge.py
@ -1,27 +1,38 @@
|
|||||||
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
import argparse
|
|
||||||
from mastodon import Mastodon
|
from mastodon import Mastodon
|
||||||
from telethon import TelegramClient, events
|
from telethon import TelegramClient, events
|
||||||
from telethon.events.common import EventBuilder
|
from telethon.tl.functions.channels import JoinChannelRequest
|
||||||
from telethon.tl.functions.channels import JoinChannelRequest, GetMessagesRequest
|
|
||||||
from telethon.tl.functions.contacts import ResolveUsernameRequest
|
from telethon.tl.functions.contacts import ResolveUsernameRequest
|
||||||
from telethon.tl.types import InputChannel
|
from telethon.tl.types import InputChannel
|
||||||
|
from telethon.utils import get_extension
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
class BridgeBot:
|
class BridgeBot:
|
||||||
def __init__(self, cfg: dict):
|
def __init__(self, cfg: dict):
|
||||||
self.config = cfg
|
self.config = cfg
|
||||||
self.mastodon_client = Mastodon(
|
self.mastodon_clients = {}
|
||||||
client_id=cfg["mastodon"]["client_id"],
|
self.tg_mstdn_mappings = {}
|
||||||
client_secret=cfg["mastodon"]["client_secret"],
|
for acc in cfg["mastodon"]["accounts"]:
|
||||||
access_token=cfg["mastodon"]["access_token"],
|
mastodon_client = Mastodon(
|
||||||
api_base_url=cfg["mastodon"]["api_base_url"]
|
client_id=acc["client_id"],
|
||||||
|
client_secret=acc["client_secret"],
|
||||||
|
access_token=acc["access_token"],
|
||||||
|
api_base_url=acc["api_base_url"]
|
||||||
)
|
)
|
||||||
|
self.mastodon_clients[acc["name"]] = mastodon_client
|
||||||
|
|
||||||
|
for m in cfg["mastodon"]["mappings"]:
|
||||||
|
if self.tg_mstdn_mappings.get("tg_channel_handle", None) is None:
|
||||||
|
self.tg_mstdn_mappings[m["tg_channel_handle"]] = []
|
||||||
|
self.tg_mstdn_mappings[m["tg_channel_handle"]].append(m["account_name"])
|
||||||
|
|
||||||
self.tg_client = TelegramClient(cfg["telegram"]["session_file"], cfg["telegram"]["api_id"],
|
self.tg_client = TelegramClient(cfg["telegram"]["session_file"], cfg["telegram"]["api_id"],
|
||||||
cfg["telegram"]["api_hash"])
|
cfg["telegram"]["api_hash"])
|
||||||
|
|
||||||
@ -33,6 +44,7 @@ class BridgeBot:
|
|||||||
channel = InputChannel(result.peer.channel_id, result.chats[0].access_hash)
|
channel = InputChannel(result.peer.channel_id, result.chats[0].access_hash)
|
||||||
await self.tg_client(JoinChannelRequest(channel))
|
await self.tg_client(JoinChannelRequest(channel))
|
||||||
self.tg_client.add_event_handler(self._tg_event_handler)
|
self.tg_client.add_event_handler(self._tg_event_handler)
|
||||||
|
logging.info("Bot has been started")
|
||||||
await self.tg_client.run_until_disconnected()
|
await self.tg_client.run_until_disconnected()
|
||||||
|
|
||||||
@events.register(events.NewMessage())
|
@events.register(events.NewMessage())
|
||||||
@ -40,19 +52,34 @@ class BridgeBot:
|
|||||||
if event.message.post:
|
if event.message.post:
|
||||||
channel = await event.get_chat()
|
channel = await event.get_chat()
|
||||||
if channel.broadcast:
|
if channel.broadcast:
|
||||||
if channel.username in self.config["telegram"]["channels"]:
|
if channel.username in self.tg_mstdn_mappings.keys():
|
||||||
print("dobbry vechur")
|
if event.message.grouped_id is not None:
|
||||||
|
logging.warning("Albums isn't supported yet")
|
||||||
|
return
|
||||||
|
logging.debug("dobbry vechur")
|
||||||
|
logging.info(f"Catched new post from telegram channel {channel.username}")
|
||||||
text: str = event.message.text
|
text: str = event.message.text
|
||||||
if event.message.forward:
|
if event.message.forward:
|
||||||
|
logging.debug("The current post is forwarded")
|
||||||
text = f"[from {event.message.forward.chat.title} (https://t.me/{event.message.forward.chat.username})]\n\n" + text
|
text = f"[from {event.message.forward.chat.title} (https://t.me/{event.message.forward.chat.username})]\n\n" + text
|
||||||
if event.message.photo:
|
temp_file_path: str = ""
|
||||||
temp_image_name = uuid.uuid4()
|
if (event.message.photo or event.message.video or event.message.gif) and not hasattr(event.message.media, "webpage"):
|
||||||
await self.tg_client.download_media(event.message.photo, f"/tmp/{temp_image_name}.jpg")
|
logging.debug("Post contains the media, downloading it...")
|
||||||
mstdn_media_meta = self.mastodon_client.media_post(f"/tmp/{temp_image_name}.jpg")
|
temp_file_name = uuid.uuid4()
|
||||||
self.mastodon_client.status_post(text, media_ids=[mstdn_media_meta])
|
temp_file_path = f"/tmp/{temp_file_name}{get_extension(event.message.media)}"
|
||||||
os.remove(f"/tmp/{temp_image_name}.jpg")
|
await self.tg_client.download_media(event.message.media, temp_file_path)
|
||||||
|
for mstdn_acc_name in self.tg_mstdn_mappings[channel.username]:
|
||||||
|
if self.mastodon_clients.get(mstdn_acc_name, None) is None:
|
||||||
|
logging.error(f"{mstdn_acc_name} doesn't exists in mastodon.accounts section of config!")
|
||||||
return
|
return
|
||||||
self.mastodon_client.toot(text)
|
current_mastodon_client = self.mastodon_clients[mstdn_acc_name]
|
||||||
|
if temp_file_path != "":
|
||||||
|
mstdn_media_meta = current_mastodon_client.media_post(temp_file_path)
|
||||||
|
current_mastodon_client.status_post(text, media_ids=[mstdn_media_meta])
|
||||||
|
else:
|
||||||
|
current_mastodon_client.toot(text)
|
||||||
|
if temp_file_path != "":
|
||||||
|
os.remove(temp_file_path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -62,6 +89,5 @@ if __name__ == '__main__':
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
config: dict = toml.loads(open(args.config, "r").read())
|
config: dict = toml.loads(open(args.config, "r").read())
|
||||||
print(config)
|
|
||||||
bot = BridgeBot(config)
|
bot = BridgeBot(config)
|
||||||
asyncio.get_event_loop().run_until_complete(bot.run())
|
asyncio.get_event_loop().run_until_complete(bot.run())
|
||||||
|
@ -1,4 +1,20 @@
|
|||||||
[mastodon]
|
[[mastodon.mappings]]
|
||||||
|
account_name = "ChronosX"
|
||||||
|
tg_channel_handle = "ChronosX_Channel"
|
||||||
|
|
||||||
|
[[mastodon.mappings]]
|
||||||
|
account_name = "floppy"
|
||||||
|
tg_channel_handle = "netwhood_news"
|
||||||
|
|
||||||
|
[[mastodon.accounts]]
|
||||||
|
name = "ChronosX"
|
||||||
|
client_id = "abc"
|
||||||
|
client_secret = "def"
|
||||||
|
access_token = "ghi"
|
||||||
|
api_base_url = "mstdn.netwhood.online"
|
||||||
|
|
||||||
|
[[mastodon.accounts]]
|
||||||
|
name = "floppy"
|
||||||
client_id = "abc"
|
client_id = "abc"
|
||||||
client_secret = "def"
|
client_secret = "def"
|
||||||
access_token = "ghi"
|
access_token = "ghi"
|
||||||
@ -7,5 +23,4 @@ api_base_url = "mstdn.netwhood.online"
|
|||||||
[telegram]
|
[telegram]
|
||||||
api_id = "123123"
|
api_id = "123123"
|
||||||
api_hash = "qwerty"
|
api_hash = "qwerty"
|
||||||
channels = [] # handles of channels without "@"
|
|
||||||
session_file = "/path/to/session/file"
|
session_file = "/path/to/session/file"
|
Loading…
Reference in New Issue
Block a user