标签 消息推送 下的文章

我一直用 Bark ,很喜欢:省心、稳定,作者也一直在更新。PushGo 这个坑某种程度上就是从 Bark 开始的,先向作者致敬🫡。

后来我自己维护的东西越来越多:服务器、CI 、脚本任务、家里设备……推送一开始还能靠“多发点提醒”解决,但很快就会变成另一种麻烦:消息很难整理。同一件事会从不同来源冒出来(监控、脚本、日志、告警),通知列表里一堆“碎片”,你要自己在脑子里拼图:到底发生了什么、现在处于什么状态、是偶发还是持续、有没有恢复。

所以我干脆自己写了个 PushGo ,目前它的定位很明确:先把“收消息 + 更好整理”做好。后面再慢慢往更通用、更可扩展的方向演进。

PushGo 的思路

PushGo 的思路和 Bark 不太一样,更像 MQTT / Ntfy 那套:频道 + 订阅( pub/sub )

你创建频道、订阅频道,消息按主题走,路由和转发会灵活很多;未来不管是扩展更多推送渠道,还是把消息类型做得更丰富,这种结构都更顺手。

  • 目前已经完成 iOS / watchOS / macOS + Android ( FCM )平台适配,全部原生开发,apple 平台使用 Swift ,Android 平台使用 Kotlin
  • WNS 和自有推送渠道正在路上,国内无法访问 FCM 的问题,自有渠道上线后就会得到解决
  • 公共网关已部署,并且支持自部署网关
  • 消息正文支持文本和部分 markdown 标签,可以渲染轻量级表格
  • 消息支持 AES-GCM 加密,网关不保留任何与解密有关的数据
  • 永久完全免费,不管客户端还是网关,纯公益运营

未来方向

  • 客户端会持续推进更多平台支持,并不仅限于高性能设备,比如目前我自己就在做一个带屏的 ESP32 设备

  • 目前客户端还很简单,也存在很多不足,尤其是 UI ,因为我自己实在没有这方面的天赋,所以 UI 只能尽量贴合系统原生,未来会持续改进优化,不断改进功能和体验,如果你有任何产品问题和建议,也可以加入 TG 群一起探讨,如果有小伙伴愿意提供 ui 设计方面的支持,欢迎 TG 私聊,感谢

  • 服务端未来会加入 MQTT 等协议支持,不仅支持消息接入,也会提供第三方注册为客户端接收消息

  • 我后面有一个比较明确的长期方向:参考 IoT 里的 物模型 概念,把一些东西(服务器、任务、设备)抽象成“模型”,用属性持续更新状态,然后在 App 端围绕这些状态做聚合展示、规则处理、报警/联动等。从消息接收器转身为综合消息枢纽,不过这个变化很大,未来尚不确定是基于 PushGo 演进,或者另开新坑

目前进度 & 参与测试

目前网关 + iOS / watchOS / macOS + Android ( FCM )都已经有初版了,也部署了公共网关,正式版预计将在一个月左右到来。

作为免费运营的公益项目,欢迎大家参与共建,为 App 和网关的持续迭代建言献策,我不希望闭门造车,大家的需求才是最重要的演进方向

截图

截图被第三方图床压缩过了,惨不忍睹,大家随便看看就好

uniappx服务端推送消息配置

一.前置条件

1.申请Dcloud 开发者账号(https://www.dcloud.io/
2.HBuilder安装
3.安装模拟器
4.uni-push 2.0 文档(https://uniapp.dcloud.net.cn/unipush-v2.html
5.创建一个uniappx项目
image.png

二.配置步骤

1.确认AppID

打开项目中 manifest.json 文件,确认AppId是否存在,若不存在则点击右侧 重新获取 按钮(此处可能需要登录Dcloud账号),会生成AppID
image.png

2.构建项目生成证书

点击 Hbuilder 菜单 运行 》 运行到手机或模拟器 》 制作自定义调试基座
image.png
点击打包,会出现打包校验提示,继续打包即可,随即会在控制台打印相关信息,此处等待时间可能较长,我们继续推进下一步,打包后台运行即可。
image.png

3.新建uniCloud

登录Dcloud 开发者中心,点击左侧uniCloud...
image.png
在新标签页中点击右上角新建服务空间,按提示完成即可,例子中建立一个叫uniapp-hello 的服务空间(取名仅作区分,无其他含义,视自己习惯命名即可);
image.png

4.创建应用信息推送

回到Dcloud开发者管理页面,点击左侧uni-push > 2.0(支持全段推送) > 应用信息
image.png
点击当前应用下拉框,选择我们需要推送的应用
image.png

选择平台视业务而定,此处示例仅勾选Android
image.png
点击选择Android包名,若包名不存在,则需等待上一步打包结束后刷新当前页面重新选择,
再添加云服务空间,选中上一步创建的空间即可,最后点击开通应用
image.png

5.创建云函数

在项目目录下的uniCloud 》coudfunctions 目录右键,选择新建云函数/云对象(若没有uniCloud目录可在项目根目录上右键,选择 创建uniCloud云开发环境 )
image.png
填写函数名点击创建即可
image.png
随后替换新建函数下的index.js 和 package.json 内容
image.png

index.js新内容如下(需替换第二行中自己的appId):


'use strict';
const uniPush = uniCloud.getPushManager({appId:"__UNI__XXXXX"}) 
exports.main = async (event, context) => {
    const body = JSON.parse(event.body);
    return await uniPush.sendMessage({
        "push_clientid": body.cid,     
        "title": body.title,    
        "content": body.content,
        "payload": body.data
    })
};
 

package.json新内容如下:

{
    "name": "photo_push",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "extensions": {
        "uni-cloud-push": {} 
    },
    "author": ""
}

6.增加uni-push 能力

在Hbuilder中打开manifest.json,勾选uni-push(消息推送)
image.png
在新建立的photo-push 目录上右键,选择 管理公共模块或扩展库依赖
image.png
选中统一推送服务,点击确定
image.png

7.增加扩展库依赖表

在database目录下增加以下依赖表文件(文件内容见结尾附件)
image.png
在 opendb-device.index.json 右键 》 初始化云数据库索引
剩余其他三个文件 右键 》 上传DB schema

8.上传部署云函数

随后在photo-push 目录点击 右键 》 上传部署,等待上传完成即可
image.png

9.云函数URL化

回到第三步创建发unicloud服务空间,点击 服务空间 名称进入详情页
在左侧 云函数/对象列表找到创建的云函数
image.png
点击函数名进入详情页,页面底部 云函数URL化编辑配置函数名 /sendMessage
注:每个服务空间内函数名不可重复,且URL路径不可出现重复部分
image.png

10.项目增加消息监听

在项目App.uvue中 onLaunch()生命函数中增加监听代码
image.png

uni.onPushMessage(res => {
                console.log("监听消息:", res)                
                if (res.type == "click") {
                    console.log("点击消息:" + res)
                }
                if (res.type == "receive") {
                    console.log("收到APP消息" + res.data);
                    // 创建本地通知栏消息
                    uni.createPushMessage({
                        title: res.data.title as string,
                        content: res.data.content as string,
                        payload: res.data.payload
                    })
                }
            }) 

11.启动项目

启动模拟器,此处以 网易Mumu模拟器 演示
Hbuilder 菜单点击 运行 》 运行到手机或模拟器 》 运行到Android App 基座
选择设备后运行,等待控制台编译完成
image.png
控制台选择 连接云端云函数
image.png

12.发起调用

使用云函数URL发起调用
image.png

效果如图
image.png
请求参数说明:

{
    "cid": ["02e3c939927d45df1028b274e493488c"], // 设备ID,长度不超过500
    "title": "绿12",
    "content": "收到消息12",
    "data": {    // data 为自定义业务参数,该字段可不传
        "type": "messageList"
    }
}

附件

●opendb-device.index.json

[
    {
        "IndexName": "index_device_id",
        "MgoKeySchema": {
            "MgoIndexKeys": [
                {
                    "Name": "device_id",
                    "Direction": "1"
                }
            ],
            "MgoIsUnique": true
        }
    }
]

●opendb-device.schema.json

{
    "bsonType": "object",
    "required": [],
    "permission": {
        "read": false,
        "create": true,
        "update": false,
        "delete": false
    },
    "properties": {
        "_id": {
            "description": "ID,系统自动生成"
        },
        "appid": {
            "bsonType": "string",
            "description": "DCloud appid"
        },
        "device_id": {
            "bsonType": "string",
            "description": "设备唯一标识"
        },
        "vendor": {
            "bsonType": "string",
            "description": "设备厂商"
        },
        "push_clientid": {
            "bsonType": "string",
            "description": "推送设备客户端标识"
        },
        "imei": {
            "bsonType": "string",
            "description": "国际移动设备识别码IMEI(International Mobile Equipment Identity)"
        },
        "oaid": {
            "bsonType": "string",
            "description": "移动智能设备标识公共服务平台提供的匿名设备标识符(OAID)"
        },
        "idfa": {
            "bsonType": "string",
            "description": "iOS平台配置应用使用广告标识(IDFA)"
        },
        "imsi": {
            "bsonType": "string",
            "description": "国际移动用户识别码(International Mobile Subscriber Identification Number)"
        },
        "model": {
            "bsonType": "string",
            "description": "设备型号"
        },
        "platform": {
            "bsonType": "string",
            "description": "平台类型"
        },
        "uni_platform": {
            "bsonType": "string",
            "description": "uni-app 运行平台,与条件编译平台相同。"
        },
        "os_name": {
            "bsonType": "string",
            "description": "ios|android|windows|mac|linux "
        },
        "os_version": {
            "bsonType": "string",
            "description": "操作系统版本号 "
        },
        "os_language": {
            "bsonType": "string",
            "description": "操作系统语言 "
        },
        "os_theme": {
            "bsonType": "string",
            "description": "操作系统主题 light|dark"
        },
        "pixel_ratio": {
            "bsonType": "string",
            "description": "设备像素比 "
        },
        "network_model": {
            "bsonType": "string",
            "description": "设备网络型号wifi\/3G\/4G\/"
        },
        "window_width": {
            "bsonType": "string",
            "description": "设备窗口宽度 "
        },
        "window_height": {
            "bsonType": "string",
            "description": "设备窗口高度"
        },
        "screen_width": {
            "bsonType": "string",
            "description": "设备屏幕宽度"
        },
        "screen_height": {
            "bsonType": "string",
            "description": "设备屏幕高度"
        },
        "rom_name": {
            "bsonType": "string",
            "description": "rom 名称"
        },
        "rom_version": {
            "bsonType": "string",
            "description": "rom 版本"
        },
        "location_latitude": {
            "bsonType": "double",
            "description": "纬度"
        },
        "location_longitude": {
            "bsonType": "double",
            "description": "经度"
        },
        "location_country": {
            "bsonType": "string",
            "description": "国家"
        },
        "location_province": {
            "bsonType": "string",
            "description": "省份"
        },
        "location_city": {
            "bsonType": "string",
            "description": "城市"
        },
        "create_date": {
            "bsonType": "timestamp",
            "description": "创建时间",
            "forceDefaultValue": {
                "$env": "now"
            }
        },
        "last_update_date": {
            "bsonType": "timestamp",
            "description": "最后一次修改时间",
            "forceDefaultValue": {
                "$env": "now"
            }
        }
    },
    "version": "0.0.1"
}

●opendb-tempdata.schema.json

{
    "bsonType": "object",
    "required": ["value", "expired"],
    "permission": {
        "read": false,
        "create": false,
        "update": false,
        "delete": false
    },
    "properties": {
        "_id": {
            "description": "ID,系统自动生成"
        },
        "value": {
            "description": "值"
        },
        "expired": {
            "description": "过期时间",
            "bsonType": "timestamp"
        }
    }
}

●uni-id-device.schema.json

{
    "bsonType": "object",
    "required": [
        "user_id"
    ],
    "properties": {
        "_id": {
            "description": "ID,系统自动生成"
        },
        "user_id": {
            "bsonType": "string",
            "description": "用户id,参考uni-id-users表"
        },
        "ua": {
            "bsonType": "string",
            "description": "userAgent"
        },
        "uuid": {
            "bsonType": "string",
            "description": "设备唯一标识(需要加密存储)"
        },
        "os_name": {
            "bsonType": "string",
            "description": "ios|android|windows|mac|linux "
        },
        "os_version": {
            "bsonType": "string",
            "description": "操作系统版本号 "
        },
        "os_language": {
            "bsonType": "string",
            "description": "操作系统语言 "
        },
        "os_theme": {
            "bsonType": "string",
            "description": "操作系统主题 light|dark"
        },
        "vendor": {
            "bsonType": "string",
            "description": "设备厂商"
        },
        "push_clientid": {
            "bsonType": "string",
            "description": "推送设备客户端标识"
        },
        "imei": {
            "bsonType": "string",
            "description": "国际移动设备识别码IMEI(International Mobile Equipment Identity)"
        },
        "oaid": {
            "bsonType": "string",
            "description": "移动智能设备标识公共服务平台提供的匿名设备标识符(OAID)"
        },
        "idfa": {
            "bsonType": "string",
            "description": "iOS平台配置应用使用广告标识(IDFA)"
        },
        "model": {
            "bsonType": "string",
            "description": "设备型号"
        },
        "platform": {
            "bsonType": "string",
            "description": "平台类型"
        },
        "create_date": {
            "bsonType": "timestamp",
            "description": "创建时间",
            "forceDefaultValue": {
                "$env": "now"
            }
        },
        "last_active_date": {
            "bsonType": "timestamp",
            "description": "最后登录时间"
        },
        "last_active_ip": {
            "bsonType": "string",
            "description": "最后登录IP"
        }
    },
    "version": "0.0.1"
}

开源微信推送服务

使用 Spring Boot 4.0 和 GraalVM Native

通过企业微信(WeCom),将系统消息稳定、合规地推送到用户的微信中接收。

整体消息流转路径如下:

HTTP 请求

企业微信 API

业务系统 / 服务

push-server

企业微信服务端

微信 App

最终效果是: 用户在微信中收到消息,但技术通道使用的是企业微信。

为什么选择企业微信?
相比微信公众号,企业微信具备天然的系统通知优势:

无缝触达:消息最终可到达 微信 App(需关注插件)。
主动推送:支持无限制的主动消息推送,适合通知。
稳定合规:官方允许的系统消息通道,不涉及内容风控。
简单易用:无需复杂的模板消息申请,开发接口清晰。

有什么需要的或者想法可以提,交流一下

项目地址

教程

1. 注册企业微信

谁都可以注册企业微信,无需认证,按说明注册并使用微信扫二维码完成管理员绑定

2. 微信插件

选择我的企业,点击微信插件,使用手机扫码关注

3. 添加应用

添加 logo 和应用名称以及可见范围,选择一个部门或者自己都行,创建应用

4. 配置应用

4.1 查看 Secret

创建完成后会进入当前页面,点击查看可以看 Secret

点击发送,可前往企业微信查看消息

点击查看,保存好,不要泄露,至关重要

4.2 配置可信 IP

在配置可信 IP 之前,我们需要先设置可信域名

可信域名需要校验域名,点击 申请校验域名 获得认证信息

下载文件放置到一个网站的根目录下,我这里放置到了自己在 cloudflare 的 Workers 和 Pages 博客上 https://mazepeng.com/

当文件可以访问到的时候就可以设置可信域名了


现在推送消息的服务必须有可信 IP,如何获得自己的 IP 呢

访问 https://ifconfig.me/ 或者直接百度 IP 就可以看到自己的公网 IP 了

点击应用管理,点击应用,拉倒最下面,配置可信 IP

5. 运行 push-server

支持 docker 部署和本地应用部署,这里我就介绍一下 docker 部署

5.1 docker 命令部署

  docker run -d \
  --name push-server \
  -p 8000:8000 \
  -e PUSH_AUTH_KEY="替换为自己的key" \
  -e PUSH_WECOM_APP_KEY="你的应用AppKey" \
  -e PUSH_WECOM_APP_SECRET="你的应用AppSecret" \
  -e PUSH_WECOM_AGENT_ID="1000001" \
  qingzhoudev/push-server:latest
  
#安全设置,默认值为下方值,需要修改添加环境变量修改
  docker run -d \
  --name push-server \
  -p 8000:8000 \
  -e PUSH_AUTH_KEY="替换为自己的key" \
  -e PUSH_WECOM_APP_KEY="你的应用AppKey" \
  -e PUSH_WECOM_APP_SECRET="你的应用AppSecret" \
  -e PUSH_WECOM_AGENT_ID="1000001" \
  -e PUSH_SECURITY_BLOCK_MINUTES="30" \
  -e PUSH_SECURITY_FAIL_WINDOW_MINUTES="5" \
  -e PUSH_SECURITY_MAX_FAILS="5" \
  -e PUSH_SECURITY_RATE_LIMIT_CAPACITY="10" \
  -e PUSH_SECURITY_RATE_LIMIT_QPS="1" \
  qingzhoudev/push-server:latest

  • PUSH_AUTH_KEY 请求头密钥,需要自己设置一个复杂的即可
  • PUSH_WECOM_APP_KEY 就是企业 ID
  • PUSH_WECOM_APP_SECRET 就是保存的 Secret
  • PUSH_WECOM_AGENT_ID 应用 ID

替换后直接 docker 启动

5.2 使用 Docker Compose

services: push-server:  qingzhoudev/push-server:latest container_name: push-server ports: - "8000:8000" volumes: - ./application-prod.yml:/app/config/application-prod.yml:ro restart: unless-stopped 

application-prod.yml 文件

push: auth: key: "CHANGE_ME" security: block-minutes: 30 fail-window-minutes: 5 max-fails: 5 rate-limit-capacity: 10 rate-limit-qps: 1 wecom: app-key: "CHANGE_ME" app-secret: "CHANGE_ME" agent-id: 1000001 webhook-url: server: port: 8000 

5.3 企业 ID

5.4 应用 ID

6 推送消息

和正常接收微信消息一样,没有什么区别

curl -X POST http://localhost:8000/api/v1/push \
  -H "X-API-Key: 替换为自己的key" \
  -H "Content-Type: application/json" \
  -d '{
"target": "ZhangSan|LiSi",
"type": "TEXT",
"content": "系统通知:您的任务已构建完成。"
}'
curl -X POST http://localhost:8000/api/v1/push \ -H "X-API-Key: 替换为自己的key" \ -H "Content-Type: application/json" \ -d '{
"target": "MaZePeng",
"type": "TEXT_CARD",
"title": "测试Push Server",
"content": "我是 Push Server,这是我作为服务端的第一条消息",
"url": "https://www.mazepeng.com"
}'
curl -X POST http://localhost:8000/api/v1/push \ -H "X-API-Key: 替换为自己的key" \ -H "Content-Type: application/json" \ -d '{
"target": "MaZePeng",
"type": "NEWS",
"articles": [
{
"title": "测试 Article",
"description": "我是描述",
"url": "https://www.mazepeng.com",
"picUrl": "https://mazepeng.com/img/bg/a_larger_image_of_the_homepage.jpg"
}
]
}'

类型有:

  • TEXT
  • MARKDOWN(微信不支持)
  • TEXT_CARD
  • NEWS

📌 转载信息
原作者:
mazp
转载时间:
2026/1/14 10:25:03