diff --git a/README.md b/README.md index 20b7ad4..babd147 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ curl -X POST 'http:///push' --data-raw '{ - [使用 Heimdallr 接收群晖DSM推送](docs/example/DSM.md) - [使用 Heimdallr 接收威联通推送](docs/example/QNAP.md) - [使用 Heimdallr 接收 GitHub star webhook](docs/example/GitHubStar.md) +- [使用 Heimdallr 接收 RSS 推送](docs/example/Rsspush.md) # 更新日志 diff --git a/docs/Api.md b/docs/Api.md index 29d2123..8cb6adf 100644 --- a/docs/Api.md +++ b/docs/Api.md @@ -1,134 +1,24 @@

接口文档

-> 接口文档有 [在线版](https://service-epwdrzxg-1255787947.gz.apigw.tencentcs.com/release/docs) ,本文档更新可能较在线版晚。 +接口文档见[这里](https://heimdallr.zeabur.app/docs)。 -# 通用 - -## channel 取值 - -目前支持以下通知渠道 - -- `bark` - [Bark](https://github.com/Finb/Bark) -- `wecom-app` - [企业微信应用消息](https://developer.work.weixin.qq.com/document/path/90236) -- `wecom-webhook` - [企业微信机器人webhook](https://developer.work.weixin.qq.com/document/path/91770) -- `pushover` - [Pushover](https://pushover.net/api) -- `pushdeer` - [PushDeer](http://pushdeer.com) -- `chanify` - [Chanify](https://github.com/chanify/chanify) -- `email`- 邮件 - -###
推送到多个渠道
- -> `v0.1.3` 后支持推送到多个渠道 - -需要推送到多个渠道时,`channel` 参数传入多个渠道,以 `+` 分隔,如 `bark+wecom-app+wecom-webhook` 。 - -# 接口 - -## Path Variable Style -`/{channel}/{title}/{body}/{key}` - -> `GET` / `POST` - -- `channel` 为推送的渠道,可以是 `bark`、`wecom-webhook`、`wecom-app` 等。 -- `title` 为推送的标题,可以是任意字符串。(可以不填) -- `body` 为推送的内容,可以是任意字符串。 -- `key` 为环境变量中设置的key,当设置了环境变量时必填。 - -## Get Param Style - -`/{channel}?title={title}&body={body}&key={key}` - -> `GET` - -- `channel` 为推送的渠道,可以是 `bark`、`wecom-webhook`、`wecom-app` 等。 -- `title` 为推送的标题,可以是任意字符串。(可以不填) -- `body` 为推送的内容,可以是任意字符串。 -- `key` 为环境变量中设置的key,当设置了环境变量时必填。 - -## JSON - -`/send` - -> `POST` - -请求参数 - -```json -{ - "channel": "string", - "title": "", - "body": "", - "key": "" -} -``` - -## Form - -`/sendForm` - -> `POST` - -- `channel` 为推送的渠道,可以是 `bark`、`wecom-webhook`、`wecom-app` 等。 -- `title` 为推送的标题,可以是任意字符串。(可以不填) -- `body` 为推送的内容,可以是任意字符串。 -- `key` 为环境变量中设置的key,当设置了环境变量时必填。 - -## Echo - -`/echo/{channel}` - -> `POST` - -- `channel` 为推送的渠道,可以是 `bark`、`wecom-webhook`、`wecom-app` 等。 -- POST 请求的 body 会原样返回。 - -## Wecom - -`/wecom-app` `/wecom-webhook` - -> `POST` - -请求参数 +## 返回示例 -```json -{ - "title": "", - "body": "", - "msg_type": "text" -} -``` - -- `msg_type` 取值可以是 `text` 或 `markdown`,默认为 `text` 。使用`markdown` 时,`body` 可以传入 Markdown 格式的文本。 - -# 返回示例 - -## 成功 +### 成功 ```json {"code": 0, "message": "success"} ``` -## 错误 +### 错误 -### 通知渠道返回错误信息 +#### 通知渠道返回错误信息 ```json {"code": 1, "message": "{channel} return {msg}"} ``` -### 不支持的渠道 - -```json -{"code": 2, "message": "{channel} is not supported"} -``` - -### 运行错误 - -```json -{"code": 3, "message": "xxx"} -``` - -### 认证错误 +#### 认证错误 ```json -{"code": -1, "message": "key not authorized"} +{"code": -1, "message": "key is invalid"} ``` \ No newline at end of file diff --git a/docs/Changelog.md b/docs/Changelog.md index 9c4a069..da1725a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,4 +1,8 @@ # 更新日志 +## v2.0.4 +- 支持 [rsspush](https://github.com/easychen/rsspush) webhook 通知。 +## v2.0.3 +- 通知渠道新增钉钉 ## v2.0.2 - 通知渠道新增 飞书/Lark Webhook ## v2.0.1 diff --git a/docs/example/DSM.md b/docs/example/DSM.md index b42e09a..76c0122 100644 --- a/docs/example/DSM.md +++ b/docs/example/DSM.md @@ -5,7 +5,7 @@ 名称随意选择即可,测试网址填入在腾讯云 Serverless中获取的url,【测试网址】按照如下复制即可。如果使用 bark ,第一个地方填bark,若使用其他,填其他方式,具体见 [接口文档](/docs/Api.md) 。 ``` -https://SERVERLESS_URL/bark?phone=123&title=hi&body=hello+world +https://example.com/key?phone=123&title=hi&body=hello+world ``` ![](http://img.ameow.xyz/202205290618022.png) diff --git a/docs/example/GitHubStar.md b/docs/example/GitHubStar.md index 9872a15..7431f1e 100644 --- a/docs/example/GitHubStar.md +++ b/docs/example/GitHubStar.md @@ -2,10 +2,10 @@ 进入 GitHub 仓库的 Settings -> Webhooks -> Add webhook。 -Payload URL 填入通知服务的地址,加上路径参数,其中 `{channel}` 为通知渠道。 +Payload URL 填入通知服务的地址,加上路径参数,其中 `{key}` 为通知渠道的 `token`。 ``` -https://example.org/github/star/{channel} +https://example.com/webhook/github/star/{key} ``` Content type 选择 `application/json`, Secret 留空。 diff --git a/docs/example/QNAP.md b/docs/example/QNAP.md index 6a967c9..efe30f2 100644 --- a/docs/example/QNAP.md +++ b/docs/example/QNAP.md @@ -5,9 +5,9 @@ SMS 服务提供商选择 【custom】,别名随意选择即可。【URL 模板】填入以下信息。剩余两项随意填写即可。 ``` -https://SERVERLESS_URL/CHANNELS?phone=@@PhoneNumber@@&title=Notification+From+QNAP&body=@@Text@@ +https://example.com/key?phone=@@PhoneNumber@@&title=Notification+From+QNAP&body=@@Text@@ ``` -`SERVERLESS_URL` 为你的服务地址,`CHANNELS` 为你的通知渠道,如果使用 bark ,第一个地方填bark,若使用其他,填其他方式,具体见 [接口文档](/docs/Api.md) 。 +`example.com` 替换为你的服务地址,`key` 为你的通知渠道的 `token`。 ![](http://img.ameow.xyz/202311010122299.png) diff --git a/docs/example/Rsspush.md b/docs/example/Rsspush.md new file mode 100644 index 0000000..e5e8e34 --- /dev/null +++ b/docs/example/Rsspush.md @@ -0,0 +1,16 @@ +

使用 Heimdallr 接收 rsspush 推送

+ +先按照 [rsspush](https://github.com/easychen/rsspush) 文档安装配置好 RSSPush。 + +在 SendKey 处,填入 Heimdallr 的 webhook,如下。 + +``` +https://example.com/webhook/rsspush/{key} +``` + +其中 `{key}` 为通知渠道的 `token`。 + +> 提示:RSSPush 没有提供测试通知渠道的方式,如果需要测试,可以把拉取时间间隔调为1分钟,然后从 [Lorem RSS](https://lorem-rss.herokuapp.com/) 这个网站复制 `https://lorem-rss.herokuapp.com/feed` 到 RSS 订阅处,即可每隔一分钟触发一次。 + +## 加餐 —— 接收 V2EX 新消息 +在 V2EX [提醒系统](https://v2ex.com/notifications) 底部有一个【Atom Feed for Notifications】,复制该地址到 RSSPush 中即可接收 V2EX 新消息推送。 \ No newline at end of file diff --git a/heimdallr/api/api.py b/heimdallr/api/api.py index 9932d36..a3b6555 100644 --- a/heimdallr/api/api.py +++ b/heimdallr/api/api.py @@ -3,5 +3,5 @@ from heimdallr.api import push, webhook router = APIRouter() -router.include_router(push.push_router) router.include_router(webhook.webhook_router) +router.include_router(push.push_router) diff --git a/heimdallr/api/push.py b/heimdallr/api/push.py index ae03e49..1bd0ade 100644 --- a/heimdallr/api/push.py +++ b/heimdallr/api/push.py @@ -20,6 +20,8 @@ async def send_push_by_form( return await serve_channels_async(key, title, body, msg_type=msg_type) +@push_router.get("/{key}") +@push_router.post("/{key}") @push_router.get("/{key}/{body}") @push_router.post("/{key}/{body}") @push_router.get("/{key}/{title}/{body}") diff --git a/heimdallr/api/webhook.py b/heimdallr/api/webhook.py index e2f12a6..ca06eb9 100644 --- a/heimdallr/api/webhook.py +++ b/heimdallr/api/webhook.py @@ -1,10 +1,13 @@ import json +import logging from fastapi import APIRouter, Request from heimdallr.api.base import serve_channels_async from heimdallr.webhook.github_star import GithubStarWebhook +logger = logging.getLogger(__name__) + webhook_router = APIRouter(prefix="/webhook") @@ -14,3 +17,13 @@ async def github_star(key: str, req: Request): webhook = GithubStarWebhook(json.loads(body)) title, msg_body, jump_url = webhook.parse() return await serve_channels_async(key, title, msg_body, jump_url=jump_url) + + +@webhook_router.post("/rsspush/{key}") +async def rsspush(key: str, req: Request): + form = await req.form() + task_title = form.get("task_title") + title = form.get("title") + desp = form.get("desp") + jump_url = form.get("link") + return await serve_channels_async(key, f"{task_title}", f"{title}\n{desp}", jump_url=jump_url) diff --git a/poetry.lock b/poetry.lock index cc3fd8f..39f5396 100644 --- a/poetry.lock +++ b/poetry.lock @@ -14,14 +14,14 @@ files = [ [[package]] name = "anyio" -version = "4.2.0" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] @@ -343,14 +343,14 @@ files = [ [[package]] name = "identify" -version = "2.5.34" +version = "2.5.35" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.34-py2.py3-none-any.whl", hash = "sha256:a4316013779e433d08b96e5eabb7f641e6c7942e4ab5d4c509ebd2e7a8994aed"}, - {file = "identify-2.5.34.tar.gz", hash = "sha256:ee17bc9d499899bc9eaec1ac7bf2dc9eedd480db9d88b96d123d3b64a9d34f5d"}, + {file = "identify-2.5.35-py2.py3-none-any.whl", hash = "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e"}, + {file = "identify-2.5.35.tar.gz", hash = "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791"}, ] [package.extras] @@ -991,19 +991,19 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "69.0.3" +version = "69.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, - {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, + {file = "setuptools-69.1.0-py3-none-any.whl", hash = "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6"}, + {file = "setuptools-69.1.0.tar.gz", hash = "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -1038,14 +1038,14 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "textual" -version = "0.50.1" +version = "0.52.1" description = "Modern Text User Interface framework" category = "dev" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "textual-0.50.1-py3-none-any.whl", hash = "sha256:11bd87fe6c543358122c43db2e9dfc5940900ef9b8975502ab7043792928638b"}, - {file = "textual-0.50.1.tar.gz", hash = "sha256:415bef44b2dfa702d17ebb08637c0141eb54767cfbeafe60d07e62104183b56a"}, + {file = "textual-0.52.1-py3-none-any.whl", hash = "sha256:960a19df2319482918b4a58736d9552cdc1ab65d170ba0bc15273ce0e1922b7a"}, + {file = "textual-0.52.1.tar.gz", hash = "sha256:4232e5c2b423ed7c63baaeb6030355e14e1de1b9df096c9655b68a1e60e4de5f"}, ] [package.dependencies] @@ -1058,14 +1058,14 @@ syntax = ["tree-sitter (>=0.20.1,<0.21.0)", "tree_sitter_languages (>=1.7.0)"] [[package]] name = "types-requests" -version = "2.31.0.20240125" +version = "2.31.0.20240218" description = "Typing stubs for requests" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240125.tar.gz", hash = "sha256:03a28ce1d7cd54199148e043b2079cdded22d6795d19a2c2a6791a4b2b5e2eb5"}, - {file = "types_requests-2.31.0.20240125-py3-none-any.whl", hash = "sha256:9592a9a4cb92d6d75d9b491a41477272b710e021011a2a3061157e2fb1f1a5d1"}, + {file = "types-requests-2.31.0.20240218.tar.gz", hash = "sha256:f1721dba8385958f504a5386240b92de4734e047a08a40751c1654d1ac3349c5"}, + {file = "types_requests-2.31.0.20240218-py3-none-any.whl", hash = "sha256:a82807ec6ddce8f00fe0e949da6d6bc1fbf1715420218a9640d695f70a9e5a9b"}, ] [package.dependencies] @@ -1100,14 +1100,14 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.2.0" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"}, - {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras]