main
 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3import contextlib
 4
 5from loguru import logger
 6from pyrogram.client import Client
 7from pyrogram.types import Message, ReplyParameters
 8
 9from config import cache
10from messages.parser import parse_msg
11from utils import i_am_bot, to_int
12
13CHART_BOT = "chartImgBot"
14
15
16async def send_to_chartimg_bridge(client: Client, message: Message, symbol: str, interval: str, target_chat: int | str | None = None, reply_msg_id: int = 0, **kwargs):  # noqa: ARG001
17    """This bridge is now deprecated. We use API from https://chart-img.com to get the chart directly.
18
19    See docs in `bridge/README.md` for details.
20
21    Args:
22        target_chat (int | str, optional): Send result to this telegram target chat. If not set, send to the trigger message's chat.
23        reply_msg_id (int, optional): If set to integer > 0, the result is sent as a reply message to this message_id.
24                                      If set to 0, reply to the trigger message itself.
25                                      If set to -1, do not send as a reply message.
26    """
27    if await i_am_bot(client):  # bot can't send message to other bots
28        return
29    target_cid = target_chat if target_chat else message.chat.id  # MSG-A's cid
30    # set MSG-A's mid
31    if to_int(reply_msg_id) == 0:
32        target_mid = message.id
33    elif to_int(reply_msg_id) == -1:
34        target_mid = None
35    else:
36        target_mid = to_int(reply_msg_id)
37    params = {
38        "target_cid": target_cid,
39        "target_mid": target_mid,
40        "text": f"{symbol} {interval}",
41        "symbol": symbol,
42        "interval": interval,
43    }
44    cache.set(f"bridge-{params['text']}", params, ttl=60)  # save params to cache
45    logger.warning(f"Trying chartimg bridge (@{CHART_BOT}): {params['text']}")
46    await client.send_message(chat_id=f"@{CHART_BOT}", text=f"/chart {params['text']}")
47
48
49async def forward_chartimg_results(client: Client, message: Message):
50    """See docs in `bridge/README.md` for details."""
51    if message.from_user.username != CHART_BOT or not message.photo:
52        return
53
54    info = parse_msg(message)
55    # got a photo message, format:
56    # [kline chart]\n{symbol} {interval}
57    if not cache.get(f"bridge-{info['text']}"):
58        return
59    params = cache.get(f"bridge-{info['text']}")
60
61    logger.info(f"Forwarding tradingview chart @{info['handle']} -> chat={params['target_cid']}, id={params['target_mid']}")
62    await client.send_photo(
63        chat_id=params["target_cid"],
64        photo=info["file_id"],
65        caption=f"[{params['symbol']}](https://www.tradingview.com/chart/?symbol={params['symbol']}) @{params['interval']} (UTC)",
66        reply_parameters=ReplyParameters(message_id=params["target_mid"]),
67    )
68    cache.delete(f"bridge-{params['text']}")
69    with contextlib.suppress(Exception):
70        if params.get("prog_cid") and params.get("prog_mid"):
71            await client.delete_messages(chat_id=params["prog_cid"], message_ids=params["prog_mid"])