Chanify 消息推送

第 1 节 概述

Chanify 是一个简单的消息推送工具。可以利用提供的 API 来发送消息推送到自己的 iOS 设备上,项目在 Github 上。安装教程可以参考这篇文章

Chanify 包括这些功能:

  • 支持自定义频道分类消息
  • 支持部署自己的节点服务器
  • 依照去中心化设计的系统架构
  • 随机账号生成保护隐私
  • 支持文本/图片/音频/文件等多种消息格式

Chanify 的功能实现主要是依赖于苹果的 APNS 服务,和 Chanify 相同原理的产品有 Bark

摘要

以下内容主要在讲我如何部署自己的节点服务器,以及配置了哪些客户端推送消息到手机。

第 2 节 添加服务端

2.1 拉取镜像

1
docker pull wizjin/chanify:latest

2.2 数据库

创建一个MySQL数据库,取名随意,例如chanify

https://img.papergate.top:5000/i/2024/12/6770367b29ef4.webp

2.3 部署镜像

1
2
3
4
5
6
7
docker run -itd --name=chanify --restart always \
-p PORT:80 \
-v /PATH/chanify/data:/root/.chanify \
-v /PATH/chanify/chanify.yml:/root/.chanify.yml \
wizjin/chanify:latest serve \
--endpoint=http://ENDPOINT_ADDRESS:PORT \
--dburl="mysql://USERNAME:PASSWORD@tcp(ADDRESS:PORT)/chanify?charset=utf8mb4&parseTime=true&loc=Local"
  • endpoint节点入口,用来访问服务端,设置为公网地址或者内网地址,比如https://message.papergate.top:5000
  • dburl非必须,不配置会使用SQLite

2.4 修改 chanify.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 服务器端
server:
	host: 0.0.0.0 # 监听地址
	port: 80 # 监听端口
	endpoint: http://ENDPOINT_ADDRESS:PORT
	name: SERVER_NAME # 服务器名称,自取
	datapath: /root/.chanify
	dburl: mysql://USERNAME:PASSWORD@tcp(ADDRESS:PORT)/chanify?charset=utf8mb4&parseTime=true&loc=Local
	http:
		- readtimeout: 10s
		- writetimeout: 10s
	register:
		enable: false # 不允许注册
		whitelist: # 白名单
			- XXXXXXXXXXXXXX # 设置自己手机 App 的用户ID

2.5 使用 App 扫码

访问网址,获取二维码:

1
http://ENDPOINT_ADDRESS:PORT

扫描二维码,添加节点。

第 3 节 添加客户端

3.1 添加频道

手机端频道页面长按右上角二维码按钮,在弹出框选择添加频道

https://img.papergate.top:5000/i/2024/12/67703f2cadf6c.webp

给频道设置名称和图标

https://img.papergate.top:5000/i/2024/12/67703f636ff3c.webp

频道页面向左滑动图标,查看详情,复制令牌备用

https://img.papergate.top:5000/i/2024/12/677040bd4f52c.webp

3.2 Chrome 浏览器推送手机

添加频道

按照之前的说法添加一个频道,比如命名为Chrome

下载插件

可以从Chrome Web Store下载插件.

插件有以下功能:

  • 发送选中的文本/图片/音频/链接消息到 Chanify
  • 发送网页链接到 Chanify

进行如下配置:

https://img.papergate.top:5000/i/2024/12/67704176a8dc2.webp

信息

中断等级的含义在下一节

选择发送目标修改为Chrome

https://img.papergate.top:5000/i/2024/12/677041c4978ac.webp

修改 chanify.yml

增加如下内容

1
2
3
4
5
6
client:
	chrome:
		sound: 1 # 是否有提示音
		endpoint: https://message.papergate.top:5000
		token: xxxxx
		interruption-level: time-sensitive

sound声音提醒:

  • 1 启用默认声音
  • 声音代码,例如 bell

interruption-level中断级别:

  • active:点亮屏幕并播放声音。
  • passive:不点亮屏幕或播放声音。
  • time-sensitive:点亮屏幕并播放声音,在“勿扰模式”期间显示。

示例

到此为止已经配置完成,比如发送一段文本

https://img.papergate.top:5000/i/2024/12/6770454eab17c.webp 在手机上便可以接收到如下内容:

https://img.papergate.top:5000/i/2024/12/677045d6b1a45.webp

3.3 威联通 Nas syslog 推送手机

添加频道

按照之前的说法添加一个频道,比如命名为Nas

配置短信服务

控制台 -> 通知中心 -> 服务账户和设备配对 -> 短信 -> 添加 SMSC 服务

https://img.papergate.top:5000/i/2024/12/6770472a90f36.webp

URL 模板格式如下,可以多配几个不同的,修改一下title的值::

1
2
3
4
5
6
7
8
# 1
http://ADDRESS:PORT/v1/sender/TOKEN?title=syslog&text=@@Text@@&sound=1&interruption-level=time-sensitive&@@PhoneNumber@@

# 2
http://ADDRESS:PORT/v1/sender/TOKEN?title=告警信息&text=@@Text@@&sound=1&interruption-level=time-sensitive&@@PhoneNumber@@

# 3
http://ADDRESS:PORT/v1/sender/TOKEN?title=应用信息&text=@@Text@@&sound=1&interruption-level=time-sensitive&@@PhoneNumber@@

https://img.papergate.top:5000/i/2024/12/677048757cf2f.webp

信息

因为@@PhoneNumber@@是必填的,所以随便放入即可

配置通知规则

控制台 -> 通知中心 -> 系统通知规则 -> 创建规则

https://img.papergate.top:5000/i/2024/12/6770490fc8de6.webp

手机号随便填写即可

多创建几个规则,用于不同情形

https://img.papergate.top:5000/i/2024/12/6770496552f01.webp

修改 chanify.yml

增加如下内容

1
2
3
4
5
6
client:
	nas:
		sound: 1 # 是否有提示音
		endpoint: https://message.papergate.top:5000
		token: xxxxx
		interruption-level: time-sensitive

sound声音提醒:

  • 1 启用默认声音
  • 声音代码,例如 bell

interruption-level中断级别:

  • active:点亮屏幕并播放声音。
  • passive:不点亮屏幕或播放声音。
  • time-sensitive:点亮屏幕并播放声音,在“勿扰模式”期间显示。

示例

https://img.papergate.top:5000/i/2024/12/67704b3624968.webp

3.4 Crawlab 推送手机

爬虫运行完成有时需要汇报一下结果,需要使用python脚本推送数据到手机

添加频道

按照之前的说法添加一个频道,比如命名为crawlab

python脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import requests

TOKEN = 'xxxxx'

def send_message(title,text):
	data = {
		'token':TOKEN,
		'title': title,
		'text': text,
		'sound': 1,
		'interruptionlevel': 'time-sensitive'
	}
	requests.post(url=f"https://ADDRESS:PORT/v1/sender/{TOKEN}", json=data)
信息

建议使用 POST 方式,以 JSON 方式传输数据,其他方式不支持设置title

修改 chanify.yml

增加如下内容

1
2
3
4
5
6
client:
	crawlab:
		sound: 1 # 是否有提示音
		endpoint: https://message.papergate.top:5000
		token: xxxxx
		interruption-level: time-sensitive

sound声音提醒:

  • 1 启用默认声音
  • 声音代码,例如 bell

interruption-level中断级别:

  • active:点亮屏幕并播放声音。
  • passive:不点亮屏幕或播放声音。
  • time-sensitive:点亮屏幕并播放声音,在“勿扰模式”期间显示。

3.5 Artalk 评论系统推送手机

添加频道

按照之前的说法添加一个频道,比如命名为comment

设置 WebHook

Artalk 后台设置一下 WebHook 要发送的 URL

https://img.papergate.top:5000/i/2024/12/67716b878703b.webp

编写后端进行解析转发

比如用 Docker 在内网环境简单搭建一个 FastApi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from fastapi import FastAPI, Request  
from urllib.parse import unquote  
from utils import send_message  

app = FastAPI()  

@app.post("/artalk")  
async def receive_webhook(request: Request):  
    # 获取请求的 JSON 数据  
    data = await request.json()  
  
    # 提取关键字段  
    comment = data.get("comment", {})  
    comment_nick = comment.get("nick", "未知用户")  
    comment_date = comment.get("date", "未知时间")  
    page_url = comment.get("page_url", "")  
    comment_content = comment.get("content", "无内容")  
  
    # 从 URL 提取文章名称并进行 URL 解码  
    try:  
        article_name_encoded = page_url.split("posts/")[1].split("/")[0]  
        article_name = unquote(article_name_encoded)  
    except (IndexError, ValueError):  
        article_name = "未知文章"  
  
    # 构造标题和内容  
    title = f"{comment_nick} 发表了评论"  
    text = f"博客名称:{article_name}\n时间:{comment_date}\n评论内容:{comment_content}"  
  
    send_message(title=title, text=text)

修改 chanify.yml

增加如下内容

1
2
3
4
5
6
client:
	comment:
		sound: 1 # 是否有提示音
		endpoint: https://message.papergate.top:5000
		token: xxxxx
		interruption-level: time-sensitive

sound声音提醒:

  • 1 启用默认声音
  • 声音代码,例如 bell

interruption-level中断级别:

  • active:点亮屏幕并播放声音。
  • passive:不点亮屏幕或播放声音。
  • time-sensitive:点亮屏幕并播放声音,在“勿扰模式”期间显示。

示例

https://img.papergate.top:5000/i/2024/12/67716c89069d4.webp

https://img.papergate.top:5000/i/2024/12/67716cc5022c1.webp