add pyTelegramBotAPI
This commit is contained in:
parent
fa4159c563
commit
f5f9f5349a
@ -6,12 +6,15 @@ from app.core import settings, MediaInfo, TorrentInfo, Context
|
|||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.utils.http import RequestUtils
|
from app.utils.http import RequestUtils
|
||||||
from app.utils.singleton import Singleton
|
from app.utils.singleton import Singleton
|
||||||
|
import telebot
|
||||||
|
|
||||||
|
from app.utils.string import StringUtils
|
||||||
|
|
||||||
|
|
||||||
class Telegram(metaclass=Singleton):
|
class Telegram(metaclass=Singleton):
|
||||||
|
_ds_url = f"http://127.0.0.1:{settings.PORT}/api/v1/messages?token={settings.API_TOKEN}"
|
||||||
_poll_timeout: int = 5
|
|
||||||
_event = Event()
|
_event = Event()
|
||||||
|
_bot: telebot.TeleBot = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
@ -21,14 +24,17 @@ class Telegram(metaclass=Singleton):
|
|||||||
self._telegram_token = settings.TELEGRAM_TOKEN
|
self._telegram_token = settings.TELEGRAM_TOKEN
|
||||||
# Chat Id
|
# Chat Id
|
||||||
self._telegram_chat_id = settings.TELEGRAM_CHAT_ID
|
self._telegram_chat_id = settings.TELEGRAM_CHAT_ID
|
||||||
# 用户Chat Id列表
|
# 初始化机器人
|
||||||
self._telegram_user_ids = settings.TELEGRAM_USERS.split(",")
|
|
||||||
# 管理员Chat Id列表
|
|
||||||
self._telegram_admin_ids = settings.TELEGRAM_ADMINS.split(",")
|
|
||||||
# 消息轮循
|
|
||||||
if self._telegram_token and self._telegram_chat_id:
|
if self._telegram_token and self._telegram_chat_id:
|
||||||
self._thread = Thread(target=self.__start_telegram_message_proxy)
|
_bot = telebot.TeleBot(self._telegram_token, parse_mode="markdown")
|
||||||
self._thread.start()
|
self._bot = _bot
|
||||||
|
|
||||||
|
@_bot.message_handler(func=lambda message: True)
|
||||||
|
def echo_all(message):
|
||||||
|
RequestUtils(timeout=10).post_res(self._ds_url, json=message.json)
|
||||||
|
|
||||||
|
# 启动轮询
|
||||||
|
_bot.infinity_polling()
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", image: str = "", userid: str = "") -> Optional[bool]:
|
def send_msg(self, title: str, text: str = "", image: str = "", userid: str = "") -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
@ -49,7 +55,7 @@ class Telegram(metaclass=Singleton):
|
|||||||
try:
|
try:
|
||||||
if text:
|
if text:
|
||||||
# text中的Markdown特殊字符转义
|
# text中的Markdown特殊字符转义
|
||||||
text = text.replace("[", r"\[").replace("_", r"\_").replace("*", r"\*").replace("`", r"\`").replace("\n\n", "\n")
|
text = StringUtils.escape_markdown(text)
|
||||||
caption = f"*{title}*\n{text}"
|
caption = f"*{title}*\n{text}"
|
||||||
else:
|
else:
|
||||||
caption = title
|
caption = title
|
||||||
@ -138,74 +144,20 @@ class Telegram(metaclass=Singleton):
|
|||||||
向Telegram发送报文
|
向Telegram发送报文
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __res_parse(result):
|
|
||||||
if result and result.status_code == 200:
|
|
||||||
ret_json = result.json()
|
|
||||||
status = ret_json.get("ok")
|
|
||||||
if status:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.error(
|
|
||||||
f"发送消息错误,错误码:{ret_json.get('error_code')},错误原因:{ret_json.get('description')}")
|
|
||||||
return False
|
|
||||||
elif result is not None:
|
|
||||||
logger.error(f"发送消息错误,错误码:{result.status_code},错误原因:{result.reason}")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
logger.error("发送消息错误,未知错误")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# 请求
|
|
||||||
request = RequestUtils(proxies=settings.PROXY)
|
|
||||||
|
|
||||||
# 发送图文消息
|
|
||||||
if image:
|
if image:
|
||||||
photo_req = request.get_res(image)
|
ret = self._bot.send_photo(chat_id=self._telegram_chat_id,
|
||||||
if photo_req and photo_req.content:
|
photo=image,
|
||||||
res = request.post_res("https://api.telegram.org/bot%s/sendPhoto" % self._telegram_token,
|
caption=caption,
|
||||||
data={"chat_id": chat_id, "caption": caption, "parse_mode": "Markdown"},
|
parse_mode="markdown")
|
||||||
files={"photo": photo_req.content})
|
else:
|
||||||
if __res_parse(res):
|
ret = self._bot.send_message(chat_id=self._telegram_chat_id,
|
||||||
return True
|
text=caption,
|
||||||
# 发送文本消息
|
parse_mode="markdown")
|
||||||
res = request.get_res("https://api.telegram.org/bot%s/sendMessage?" % self._telegram_token + urlencode(
|
|
||||||
{"chat_id": chat_id, "text": caption, "parse_mode": "Markdown"}))
|
|
||||||
return __res_parse(res)
|
|
||||||
|
|
||||||
def __start_telegram_message_proxy(self):
|
return True if ret else False
|
||||||
logger.info("Telegram消息接收服务启动")
|
|
||||||
|
|
||||||
def consume_messages(_offset: int, _sc_url: str, _ds_url: str) -> int:
|
|
||||||
try:
|
|
||||||
res = RequestUtils(proxies=settings.PROXY).get_res(
|
|
||||||
_sc_url + urlencode({"timeout": self._poll_timeout, "offset": _offset}))
|
|
||||||
if res and res.json():
|
|
||||||
for msg in res.json().get("result", []):
|
|
||||||
# 无论本地是否成功,先更新offset,即消息最多成功消费一次
|
|
||||||
_offset = msg["update_id"] + 1
|
|
||||||
logger.debug("Telegram接收到消息: %s" % msg)
|
|
||||||
local_res = RequestUtils(timeout=10).post_res(_ds_url, json=msg)
|
|
||||||
logger.debug("Telegram message: %s processed, response is: %s" % (msg, local_res.text))
|
|
||||||
except Exception as e:
|
|
||||||
logger.error("Telegram 消息接收出现错误: %s" % e)
|
|
||||||
return _offset
|
|
||||||
|
|
||||||
offset = 0
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if self._event.is_set():
|
|
||||||
logger.info("Telegram消息接收服务已停止")
|
|
||||||
break
|
|
||||||
index = 0
|
|
||||||
while index < 20 and not self._event.is_set():
|
|
||||||
offset = consume_messages(_offset=offset,
|
|
||||||
_sc_url="https://api.telegram.org/bot%s/getUpdates?" % self._telegram_token,
|
|
||||||
_ds_url="http://127.0.0.1:%s/api/v1/messages?token=%s" % (
|
|
||||||
settings.PORT, settings.API_TOKEN))
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
停止Telegram消息接收服务
|
停止Telegram消息接收服务
|
||||||
"""
|
"""
|
||||||
self._event.set()
|
self._bot.stop_polling()
|
||||||
|
@ -512,3 +512,21 @@ class StringUtils:
|
|||||||
大写首字母兼容None
|
大写首字母兼容None
|
||||||
"""
|
"""
|
||||||
return s.title() if s else s
|
return s.title() if s else s
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def escape_markdown(content: str) -> str:
|
||||||
|
"""
|
||||||
|
Escapes Markdown characters in a string of Markdown.
|
||||||
|
|
||||||
|
Credits to: simonsmh
|
||||||
|
|
||||||
|
:param content: The string of Markdown to escape.
|
||||||
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:return: The escaped string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
|
"""
|
||||||
|
|
||||||
|
parses = re.sub(r"([_*\[\]()~`>#+\-=|.!{}])", r"\\\1", content)
|
||||||
|
reparse = re.sub(r"\\\\([_*\[\]()~`>#+\-=|.!{}])", r"\1", parses)
|
||||||
|
return reparse
|
||||||
|
@ -35,4 +35,5 @@ func_timeout==4.3.5
|
|||||||
selenium~=4.9.1
|
selenium~=4.9.1
|
||||||
bs4~=0.0.1
|
bs4~=0.0.1
|
||||||
beautifulsoup4~=4.12.2
|
beautifulsoup4~=4.12.2
|
||||||
pillow==9.5.0
|
pillow~=9.5.0
|
||||||
|
pyTelegramBotAPI~=4.12.0
|
Loading…
x
Reference in New Issue
Block a user