Skip to content

Commit 575fd24

Browse files
authored
Minor generalization of TG message sending code (#184)
1 parent 996aac4 commit 575fd24

File tree

1 file changed

+57
-18
lines changed

1 file changed

+57
-18
lines changed

fink_utils/tg_bot/utils.py

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import pandas as pd
2222
import numpy as np
2323
import gzip
24+
import re
2425
from astropy.io import fits
2526

2627
import matplotlib.pyplot as plt
@@ -31,6 +32,20 @@
3132
COLORS_ZTF = {1: "#15284F", 2: "#F5622E"}
3233

3334

35+
def escape(text):
36+
"""Escapes the text as needed for MarkdownV2 parse_mode
37+
38+
Parameters
39+
----------
40+
text : Text to escape
41+
42+
Returns
43+
-------
44+
result : str
45+
"""
46+
return re.sub(r'[_*[\]()~>#\+\-=|{}.!]', lambda x: '\\' + x.group(), text)
47+
48+
3449
def status_check(res, header, sleep=8, timeout=25):
3550
"""Checks whether the request was successful.
3651
@@ -86,7 +101,7 @@ def send_simple_text_tg(text, channel_id, timeout=25):
86101
status_check(res, header=channel_id)
87102

88103

89-
def msg_handler_tg(tg_data, channel_id, init_msg, timeout=25):
104+
def msg_handler_tg(tg_data, channel_id, init_msg=None, timeout=25, sleep_seconds=10, parse_mode="markdown"):
90105
"""Send `tg_data` to a telegram channel
91106
92107
Notes
@@ -100,14 +115,19 @@ def msg_handler_tg(tg_data, channel_id, init_msg, timeout=25):
100115
Content of the tuple:
101116
text_data : str
102117
Notification text
103-
cutout : BytesIO stream
104-
cutout image in png format
118+
cutout : BytesIO stream or str
119+
cutout image in png format, image url, or a list of these
105120
curve : BytesIO stream
106121
light curve picture
107122
channel_id: string
108123
Channel id in Telegram
109124
init_msg: str
110125
Initial message
126+
timeout: int
127+
Timeout when sending message. Default is 25 seconds.
128+
sleep_seconds: int
129+
How many seconds to sleep between two messages to avoid
130+
code 429 from the Telegram API. Default is 10 seconds.
111131
112132
Returns
113133
-------
@@ -117,29 +137,48 @@ def msg_handler_tg(tg_data, channel_id, init_msg, timeout=25):
117137
url += os.environ["FINK_TG_TOKEN"]
118138
method = url + "/sendMediaGroup"
119139

120-
if init_msg != "":
121-
send_simple_text_tg(init_msg, channel_id, timeout=25)
140+
files = {}
141+
media = []
142+
143+
def add(data, text=None, parse_mode=parse_mode):
144+
# TODO: handle text-only messages?
145+
item = {
146+
"type": "photo",
147+
}
148+
149+
if isinstance(data, str):
150+
item["media"] = data
151+
elif data is not None:
152+
fname = "file{}".format(len(files))
153+
files[fname] = data
154+
item["media"] = "attach://{}".format(fname)
155+
156+
if text is not None:
157+
item["caption"] = text
158+
item["parse_mode"] = parse_mode
159+
160+
media.append(item)
161+
162+
if init_msg:
163+
send_simple_text_tg(init_msg, channel_id, timeout=timeout)
122164
for text_data, cutout, curve in tg_data:
123-
files = {"first": curve}
124-
media = [
125-
{
126-
"type": "photo",
127-
"media": "attach://first",
128-
"caption": text_data,
129-
"parse_mode": "markdown",
130-
}
131-
]
132-
if cutout is not None:
133-
files.update({"second": cutout})
134-
media.append({"type": "photo", "media": "attach://second"})
165+
if curve is not None:
166+
add(curve, text_data)
167+
168+
if isinstance(cutout, list):
169+
for c in cutout:
170+
add(c)
171+
else:
172+
add(cutout)
173+
135174
res = requests.post(
136175
method,
137176
params={"chat_id": channel_id, "media": str(media).replace("'", '"')},
138177
files=files,
139178
timeout=timeout,
140179
)
141180
status_check(res, header=channel_id)
142-
time.sleep(10)
181+
time.sleep(sleep_seconds)
143182

144183

145184
def msg_handler_tg_cutouts(tg_data, channel_id, init_msg, timeout=25, sleep_seconds=10):

0 commit comments

Comments
 (0)