diff --git a/README.md b/README.md index a27720c..f3cf21b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Heimdallr 是一个非常轻量的通知网关,可以聚合各种推送渠道 - [飞书/Lark](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot) - [钉钉自定义机器人](https://open.dingtalk.com/document/robots/custom-robot-access) - [Apprise](https://github.com/caronc/apprise) +- [PushMe](https://push.i-i.me/) > 如果有需要的通知方式,请提交 [issue](https://github.com/LeslieLeung/heimdallr/issues/new?assignees=LeslieLeung&labels=enhancement&template=feature_request.md&title=) diff --git a/docs/Config.md b/docs/Config.md index c0ad0f7..c1744f6 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -111,6 +111,8 @@ channel_3_WECOM_WEBHOOK_KEY= | `DINGTALK_TOKEN` | 钉钉 | 钉钉的自定义机器人 Token,见 [这里](https://open.dingtalk.com/document/robots/custom-robot-access)。取其 `access_token` 部分。 | | `DINGTALK_SAFE_WORDS` | 钉钉 | 钉钉的关键词。 | | `APPRISE_URL` | Apprise | Apprise 的协议 URL,见 [这里](https://github.com/caronc/apprise#supported-notifications) | +| `PUSHME_URL` | PushMe | PushMe 的服务端地址 | +| `PUSHME_PUSH_KEY` | PushMe | ## 腾讯云 Serverless 环境变量设置 diff --git a/heimdallr/channel/apprise.py b/heimdallr/channel/apprise.py index ab818a9..f40cd33 100644 --- a/heimdallr/channel/apprise.py +++ b/heimdallr/channel/apprise.py @@ -69,7 +69,6 @@ def _handle_attach(attach: str) -> str: return attach os.makedirs("tmp", exist_ok=True) file_path = os.path.join("tmp", "attach") - # decode base64 string bf = base64.b64decode(attach) ext = filetype.guess_extension(bf) @@ -78,7 +77,6 @@ def _handle_attach(attach: str) -> str: file_path = f"{file_path}.{ext}" with open(file_path, "wb") as f: - # decode base64 string f.write(bf) return file_path diff --git a/heimdallr/channel/factory.py b/heimdallr/channel/factory.py index 83501be..141ff52 100644 --- a/heimdallr/channel/factory.py +++ b/heimdallr/channel/factory.py @@ -10,6 +10,7 @@ from heimdallr.channel.lark import LarkWebhook, LarkWebhookMessage from heimdallr.channel.ntfy import Ntfy, NtfyMessage from heimdallr.channel.pushdeer import PushDeer, PushDeerMessage +from heimdallr.channel.pushme import Pushme, PushmeMessage from heimdallr.channel.pushover import Pushover, PushoverMessage from heimdallr.channel.telegram import Telegram, TelegramMessage from heimdallr.channel.wecom import ( @@ -38,6 +39,7 @@ CHANNEL_LARK_WEBHOOK = "lark_webhook" CHANNEL_DINGTALK_WEBHOOK = "dingtalk_webhook" CHANNEL_APPRISE = "apprise" +CHANNEL_PUSHME = "pushme" def _get_channel_type_by_name(name: str) -> str: @@ -81,6 +83,8 @@ def build_channel(name: str) -> Channel: return DingTalk(name, channel_type) elif channel_type == CHANNEL_APPRISE: return Apprise(name, channel_type) + elif channel_type == CHANNEL_PUSHME: + return Pushme(name, channel_type) else: raise ParamException(f"Channel {name} type {channel_type} not supported.") @@ -117,5 +121,7 @@ def build_message(name: str, title: str, body: str, **kwargs) -> Message: return DingTalkMessage(title, body, **kwargs) elif channel_type == CHANNEL_APPRISE: return AppriseMessage(title, body, **kwargs) + elif channel_type == CHANNEL_PUSHME: + return PushmeMessage(title, body, **kwargs) else: raise ParamException(f"Channel type {channel_type} not supported.") diff --git a/heimdallr/channel/pushme.py b/heimdallr/channel/pushme.py new file mode 100644 index 0000000..20d727d --- /dev/null +++ b/heimdallr/channel/pushme.py @@ -0,0 +1,44 @@ +import logging +from typing import Mapping, Tuple + +import requests + +from heimdallr.channel.base import Channel, Message +from heimdallr.config.config import get_config_str +from heimdallr.config.definition import SUFFIX_PUSHME_PUSH_KEY, SUFFIX_PUSHME_URL +from heimdallr.exception import ParamException + +logger = logging.getLogger(__name__) + + +class PushmeMessage(Message): + def __init__(self, title: str, body: str, **kwargs) -> None: + super().__init__(title, body) + + def render_message(self) -> Mapping[str, str]: + return {"title": self.title, "contents": self.body} + + +class Pushme(Channel): + def __init__(self, name: str, type: str) -> None: + super().__init__(name, type) + self.base_url: str = "https://push.i-i.me" + self.push_key: str + self._build_channel() + + def _build_channel(self) -> None: + self.base_url = get_config_str(self.get_name(), SUFFIX_PUSHME_URL, self.base_url) + self.push_key = get_config_str(self.get_name(), SUFFIX_PUSHME_PUSH_KEY, "") + if self.push_key == "": + raise ParamException("Pushme push key cannot be empty.") + + def send(self, message: Message) -> Tuple[bool, str]: + """ + Send a message to pushme server. + """ + param = message.render_message() + param["push_key"] = self.push_key + rs = requests.get(self.base_url, params=param) + if rs.status_code != 200: + logger.error(f"Pushme send failed: {rs.text}") + return rs.status_code == 200, rs.text diff --git a/heimdallr/config/definition.py b/heimdallr/config/definition.py index 60329f9..c8a1cce 100644 --- a/heimdallr/config/definition.py +++ b/heimdallr/config/definition.py @@ -48,3 +48,6 @@ SUFFIX_DINGTALK_SAFE_WORDS = "DINGTALK_SAFE_WORDS" # apprise SUFFIX_APPRISE_URL = "APPRISE_URL" +# pushme +SUFFIX_PUSHME_URL = "PUSHME_URL" +SUFFIX_PUSHME_PUSH_KEY = "PUSHME_PUSH_KEY"