Skip to content

Commit

Permalink
add support for multiple DC groups per gateway and vice versa
Browse files Browse the repository at this point in the history
  • Loading branch information
adbenitez committed Mar 18, 2024
1 parent 26cd428 commit f6b51bf
Showing 1 changed file with 38 additions and 28 deletions.
66 changes: 38 additions & 28 deletions matterdelta/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,43 @@
import base64
import json
import logging
import os
import tempfile
import time
from pathlib import Path
from threading import Thread
from typing import Dict, List, Tuple

import requests
from deltabot_cli import AttrDict, Bot, ViewType

mb_config = {}
chat2gateway = {}
gateway2chat = {}
chat2gateway: Dict[Tuple[int, int], List[str]] = {}
gateway2chat: Dict[str, List[Tuple[int, int]]] = {}


def init_api(bot: Bot, config_dir: str) -> None:
"""Load matterbridge API configuration and start listening to the API endpoint."""
path = os.path.join(config_dir, "config.json")
if os.path.exists(path):
with open(path, encoding="utf-8") as config:
path = Path(config_dir) / "config.json"
if path.exists():
with path.open(encoding="utf-8") as config:
mb_config.update(json.load(config))
gateways = mb_config.get("gateways", [])

for gateway in mb_config.get("gateways") or []:
for gateway in gateways:
chat = (gateway["accountId"], gateway["chatId"])
gateway2chat[gateway["gateway"]] = chat
chat2gateway[chat] = gateway["gateway"]
gateway2chat.setdefault(gateway["gateway"], []).append(chat)
chat2gateway.setdefault(chat, []).append(gateway["gateway"])

if len(mb_config.get("gateways") or []):
Thread(target=listen_to_matterbridge, args=(bot,)).start()
if mb_config["api"]["url"] and len(gateways):
Thread(target=listen_to_matterbridge, args=(bot,), daemon=True).start()


def dc2mb(bot: Bot, accid: int, msg: AttrDict) -> None:
"""Send a Delta Chat message to the matterbridge side."""
gateway = chat2gateway.get((accid, msg.chat_id))
if gateway:
if not msg.text and not msg.file: # ignore buggy empty messages
return
api_url = mb_config["api"]["url"]
token = mb_config["api"].get("token", "")
headers = {"Authorization": f"Bearer {token}"} if token else None
if not msg.text and not msg.file: # ignore buggy empty messages
return
gateways = chat2gateway.get((accid, msg.chat_id), [])
if gateways:
username = (
msg.override_sender_name
or bot.rpc.get_contact(accid, msg.sender.id).display_name
Expand All @@ -60,23 +59,32 @@ def dc2mb(bot: Bot, accid: int, msg: AttrDict) -> None:
QUOTENICK=quotenick,
QUOTEMESSAGE=" ".join(msg.quote.text.split()),
)
data = {"gateway": gateway, "username": username, "text": text, "event": event}
data = {"username": username, "text": text, "event": event}
if msg.file:
with open(msg.file, mode="rb") as attachment:
enc_data = base64.standard_b64encode(attachment.read()).decode()
data["Extra"] = {
"file": [{"Name": msg.file_name, "Data": enc_data, "Comment": text}]
}
logging.debug("DC->MB %s", data)
requests.post(api_url + "/api/message", json=data, headers=headers, timeout=60)
api_url = mb_config["api"]["url"]
token = mb_config["api"].get("token", "")
headers = {"Authorization": f"Bearer {token}"} if token else None
for gateway in gateways:
data["gateway"] = gateway
logging.debug("DC->MB %s", data)
if api_url:
requests.post(
api_url + "/api/message", json=data, headers=headers, timeout=60
)
mb2dc(bot, data, (accid, msg.chat_id))


def mb2dc(bot: Bot, msg: dict) -> None:
def mb2dc(bot: Bot, msg: dict, exclude: tuple[int, int] = (0, 0)) -> None:
"""Send a message from matterbridge to the bridged Delta Chat group"""
if msg["event"] not in ("", "user_action"):
return
accid, chat_id = gateway2chat.get(msg["gateway"]) or (0, 0)
if not accid or not chat_id:
chats = [c for c in gateway2chat.get(msg["gateway"], []) if c != exclude]
if not chats:
return
text = msg.get("text") or ""
if msg["event"] == "user_action":
Expand All @@ -90,15 +98,17 @@ def mb2dc(bot: Bot, msg: dict) -> None:
if text == file["Name"]:
text = ""
with tempfile.TemporaryDirectory() as tmp_dir:
reply["file"] = os.path.join(tmp_dir, file["Name"])
reply["file"] = str(Path(tmp_dir, file["Name"]))
data = base64.decodebytes(file["Data"].encode())
with open(reply["file"], mode="wb") as attachment:
attachment.write(data)
if file["Name"].endswith((".tgs", ".webp")):
reply["viewtype"] = ViewType.STICKER
bot.rpc.send_msg(accid, chat_id, reply)
for accid, chat_id in chats:
bot.rpc.send_msg(accid, chat_id, reply)
elif text:
bot.rpc.send_msg(accid, chat_id, reply)
for accid, chat_id in chats:
bot.rpc.send_msg(accid, chat_id, reply)


def listen_to_matterbridge(bot: Bot) -> None:
Expand All @@ -118,5 +128,5 @@ def listen_to_matterbridge(bot: Bot) -> None:
mb2dc(bot, msg)
time.sleep(1)
except Exception as ex: # pylint: disable=W0703
time.sleep(5)
logging.exception(ex)
time.sleep(15)

0 comments on commit f6b51bf

Please sign in to comment.