# MessagePush **Repository Path**: fightroad/message-push ## Basic Information - **Project Name**: MessagePush - **Description**: No description available - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-11-03 - **Last Updated**: 2026-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MessagePush 一个支持多通道的消息推送服务,目前支持: - 微信模板消息推送(轻量级实现,无需第三方库) - MessagePusher 推送 - 阿里云短信 - 腾讯云短信 - 邮件发送(SMTP) - Apple 推送(APNs) - Google 推送(FCM) - Telegram Bot 推送 - Bark 推送(iOS 自定义推送服务) - 华为推送(HMS Core Push Kit) - 小米推送(Mi Push) - Vivo 推送 - OPPO 推送 ## 配置说明 配置文件 `appsettings.json`: ```json { "Log": { "MinimumLevel": "Information", // 日志级别:Trace/Debug/Information/Warning/Error/Fatal "EnableConsole": true, // 是否启用控制台日志 "RetainedDays": 30, // 日志文件保留天数 "FileSizeLimitBytes": 10485760 // 单个日志文件大小限制(字节),默认 10MB }, "EnableSwagger": true, // 是否启用 Swagger API 文档 "EnableMessageQueue": false, // 是否启用消息队列模式(默认 false,使用同步模式) "Kestrel": { "Endpoints": { "Http": { "Url": "http://*:5000" // 服务监听地址和端口 } } }, "DbConfig": { "Type": "Sqlite", // 数据库类型:Sqlite/MySql/Mssql/Pgsql "ConnectionString": "Data Source=db/MessagePush.db" // 数据库连接字符串 }, "AuthTokens": { "test1": "1234567890", // API ID 和 Key 的映射 "test2": "0987654321" }, "Weixin": { "AppId": "your_appid", "AppSecret": "your_secret" }, "TelegramBot": { "BotToken": "your_bot_token" }, "MessagePusher": { "ServerAddress": "https://msgpusher.com", "UserName": "your_username", "Token": "your_token" }, "AliyunSms": { "AccessKeyId": "your_access_key_id", "AccessKeySecret": "your_access_key_secret", "SignName": "默认签名" }, "TencentSms": { "SecretId": "your_secret_id", "SecretKey": "your_secret_key", "SdkAppId": "your_sdk_app_id", "Region": "ap-beijing", "SignName": "默认签名" }, "Email": { "SmtpHost": "smtp.example.com", "SmtpPort": 587, "UserName": "your_email@example.com", "Password": "your_password", "EnableSsl": true, "FromAddress": "your_email@example.com", "FromDisplayName": "系统通知" }, "ApplePush": { "P8PrivateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----", "P8PrivateKeyId": "ABC123XYZ9", "TeamId": "ABCD123456", "AppBundleIdentifier": "com.example.app", "ServerType": "production" }, "GooglePush": { "ServerKey": "your_fcm_server_key", "SenderId": "your_sender_id" }, "Bark": { "ServerUrl": "https://api.day.app" }, "HuaweiPush": { "AppId": "your_app_id", "AppSecret": "your_app_secret" }, "XiaoMiPush": { "AppSecret": "your_app_secret" }, "VivoPush": { "AppId": "your_app_id", "AppKey": "your_app_key", "AppSecret": "your_app_secret" }, "OppoPush": { "AppKey": "your_app_key", "MasterSecret": "your_master_secret" } } ``` ## API 使用说明 ### 接口认证 所有 API 接口都需要在请求头中提供认证信息: ```http X-API-ID: your_api_id X-API-KEY: your_api_key ``` **说明:** - `X-API-ID` 和 `X-API-KEY` 需要在 `appsettings.json` 的 `AuthTokens` 中配置 - 认证失败会返回 `401 Unauthorized` 状态码 ### 发送消息接口 **接口地址:** `POST /api/Message/SendMessage` **请求头:** ```http X-API-ID: your_api_id X-API-KEY: your_api_key Content-Type: application/json ``` **请求体:** JSON 格式,见下方各通道类型的示例 **响应说明:** - **同步模式**(`EnableMessageQueue: false`): ```json { "success": true, "messageId": "abc123..." } ``` 或失败时: ```json { "success": false, "message": "错误信息" } ``` - **队列模式**(`EnableMessageQueue: true`): ```json { "success": true, "messageId": "abc123...", "queued": true, "message": "消息已加入队列,正在处理" } ``` 消息会异步处理,接口立即返回,不等待实际发送结果。 ### 消息队列模式说明 服务支持两种消息处理模式: #### 同步模式(默认) - **配置**:`EnableMessageQueue: false` - **特点**: - 接口会等待消息发送完成后再返回结果 - 可以立即知道消息是否发送成功 - 适合低并发场景或需要立即确认结果的场景 - 如果消息发送较慢,会阻塞接口响应 #### 队列模式(异步) - **配置**:`EnableMessageQueue: true` - **特点**: - 消息加入队列后立即返回,不等待实际发送 - 后台服务异步处理消息队列 - 适合高并发场景,提高接口响应速度 - 队列容量:10000 条消息(超过后等待) - 消息处理结果会记录到数据库,可通过查询接口查看 **使用建议:** - 低并发场景(< 100 QPS):使用同步模式 - 高并发场景(> 100 QPS):使用队列模式 - 需要立即确认结果:使用同步模式 - 可以接受异步处理:使用队列模式 ### 微信模板消息推送示例 #### 基础示例(网页跳转) ```json { "channelType": 1, "receiver": "onRLv7OYFGjSn8kksMzOeterkSB0", "data": { "templateId": "j_zY-Bc2sbytFRXIW0dtIhGidfOFUc75JVOiuRsEQ_w", "url": "https://www.baidu.com", "templateData": { "title": { "value": "这是标题", "color": "#173177" }, "description": { "value": "这是描述内容", "color": "#173177" }, "content": { "value": "这是详细内容", "color": "#173177" } } } } ``` #### 小程序跳转示例 ```json { "channelType": 1, "receiver": "onRLv7OYFGjSn8kksMzOeterkSB0", "data": { "templateId": "j_zY-Bc2sbytFRXIW0dtIhGidfOFUc75JVOiuRsEQ_w", "miniprogram": { "appid": "wx1234567890abcdef", "pagepath": "pages/index/index?id=123" }, "templateData": { "title": { "value": "这是标题", "color": "#173177" } } } } ``` **注意:** - `receiver` 为用户的 OpenID - `templateId` 为模板消息 ID(需要在微信公众平台申请) - `url` 和 `miniprogram` 二选一,都不填则不跳转 - `templateData` 中的 key 需要与模板中的变量名对应 - `color` 为可选参数,默认为 `#173177` ### MessagePusher 推送示例 ```json { "channelType": 2, "receiver": "username", // 要推送给的用户名,不填则推送给自己 "data": { "title": "测试标题", "description": "这是一条测试描述", "content": "# 这是 Markdown 格式的内容\n\n- 支持 Markdown\n- 可以换行\n- 可以加粗**重要内容**", "url": "https://example.com", // 可选:点击消息跳转的链接 "channel": "default" // 可选:指定推送通道 } } ``` ### 阿里云短信推送示例 ```json { "channelType": 3, "receiver": "13800138000", "data": { "templateCode": "SMS_123456", "signName": "你的签名", // 可选,不填则使用配置中的默认签名 "templateParams": { "code": "123456" } } } ``` ### 腾讯云短信推送示例 ```json { "channelType": 4, "receiver": "13800138000", "data": { "templateId": "123456", "signName": "你的签名", // 可选,不填则使用配置中的默认签名 "templateParams": ["123456"] // 可以是数组或字典 } } ``` ### 邮件发送示例 ```json { "channelType": 5, "receiver": "user@example.com", // 多个收件人可用逗号或分号分隔:user1@example.com,user2@example.com "data": { "subject": "测试邮件", "body": "
支持 HTML 格式
", "isHtml": true, // 可选,默认为 false(纯文本) "cc": "cc@example.com", // 可选:抄送 "bcc": "bcc@example.com", // 可选:密送 "priority": "high", // 可选:high/normal/low,默认 normal "attachments": ["/path/to/file1.pdf", "/path/to/file2.jpg"] // 可选:附件文件路径数组 } } ``` **注意:** - `subject` 和 `body` 为必需字段 - `isHtml` 为可选,默认为 `false`(纯文本格式) - 支持多个收件人,用逗号或分号分隔 - 附件路径必须是服务器上的绝对路径或相对路径 ### Apple 推送示例(APNs) #### 方式一:使用完整的 notification 对象 ```json { "channelType": 8, "receiver": "device_token_here", "data": { "notification": { "aps": { "alert": { "title": "通知标题", "body": "通知内容" }, "sound": "default", "badge": 1 }, "customKey": "customValue" }, "serverType": "production", // 可选:development 或 production,默认 production "apnsId": "optional_apns_id", // 可选 "apnsExpiration": 0, // 可选:过期时间(Unix 时间戳),0 表示不过期 "apnsPriority": 10, // 可选:优先级,10(立即)或 5(省电),默认 10 "isBackground": false // 可选:是否为后台推送,默认 false } } ``` #### 方式二:使用简化的参数 ```json { "channelType": 8, "receiver": "device_token_here", "data": { "title": "通知标题", "body": "通知内容", "sound": "default", // 可选 "badge": 1, // 可选 "serverType": "production" // 可选 } } ``` **注意:** - `receiver` 为设备的 Device Token - `notification` 字段的格式需符合 [Apple Push Notification 规范](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html) - `serverType` 用于切换开发/生产环境,默认为 `production` ### Google 推送示例(FCM) #### 方式一:使用完整的 payload 对象 ```json { "channelType": 9, "receiver": "device_token_or_topic", "data": { "payload": { "notification": { "title": "通知标题", "body": "通知内容", "sound": "default", "icon": "ic_notification", "click_action": "OPEN_ACTIVITY" }, "data": { "key1": "value1", "key2": "value2" } } } } ``` #### 方式二:使用简化的参数 ```json { "channelType": 9, "receiver": "device_token_or_topic", "data": { "title": "通知标题", "body": "通知内容", "sound": "default", // 可选 "icon": "ic_notification", // 可选 "clickAction": "OPEN_ACTIVITY", // 可选 "data": { // 可选:自定义数据 "key1": "value1", "key2": "value2" } } } ``` **注意:** - `receiver` 可以是设备 Token、主题(Topic)或条件(Condition) - `payload` 字段的格式需符合 [FCM 消息格式](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications) - `data` 字段中的自定义数据会传递给应用 ### 查询消息列表接口 **接口地址:** `GET /api/Message/List` **请求头:** ```http X-API-ID: your_api_id X-API-KEY: your_api_key ``` **查询参数(均为可选):** - `startTime`: 开始时间(ISO 8601 格式,如:`2024-01-01T00:00:00`) - `endTime`: 结束时间(ISO 8601 格式,如:`2024-12-31T23:59:59`) - `filterApiId`: 过滤指定的 API ID - `channelType`: 过滤通道类型(1-13,见下方通道类型说明) - `success`: 过滤成功/失败状态(`true` 或 `false`) **请求示例:** ```http GET /api/Message/List?startTime=2024-01-01T00:00:00&channelType=1&success=true X-API-ID: your_api_id X-API-KEY: your_api_key ``` **响应示例:** ```json { "success": true, "data": [ { "messageId": "d8f1a3b2c4e5f6g7h8i9j0k1l2m3n4o5", "apiId": "test1", "channelType": 1, "receiver": "onRLv7OYFGjSn8kksMzOeterkSB0", "requestData": "{\"receiver\":\"...\",\"data\":{...}}", "success": true, "createTime": "2024-01-01T12:00:00" } ], "count": 1 } ``` ### 响应示例 **发送消息接口响应:** ```json // 成功 { "success": true, "messageId": "d8f1a3b2c4e5f6g7h8i9j0k1l2m3n4o5" } // 失败 { "success": false, "message": "错误信息" } ``` **状态码说明:** - `200 OK`: 请求成功 - `400 Bad Request`: 请求参数错误(如:通道类型不支持、接收者为空等) - `401 Unauthorized`: 认证失败(API ID 或 API Key 无效) - `500 Internal Server Error`: 服务器内部错误 ### Telegram Bot 推送示例 #### 发送文本消息 ```json { "channelType": 6, "receiver": "445311964", "data": { "text": "这是一条测试消息", "parseMode": "HTML", "disableWebPagePreview": false, "disableNotification": false } } ``` #### 发送图片 ```json { "channelType": 6, "receiver": "445311964", "data": { "photo": "https://example.com/image.jpg", "caption": "图片说明", "parseMode": "HTML" } } ``` #### 发送文档 ```json { "channelType": 6, "receiver": "123456789", "data": { "document": "https://example.com/file.pdf", "caption": "文档说明" } } ``` **注意:** - `receiver` 为 Chat ID(用户 ID 或群组 ID) - `parseMode` 可选:`HTML`、`Markdown`、`MarkdownV2` - `text`、`photo`、`document` 三选一 - 图片和文档支持 URL 或文件 ID ### Bark 推送示例 #### 基础示例 ```json { "channelType": 7, "receiver": "your_device_key", "data": { "title": "测试通知", "body": "这是一条测试消息" } } ``` #### 完整参数示例 ```json { "channelType": 7, "receiver": "your_device_key", "data": { "title": "重要通知", "subtitle": "副标题", "body": "这是一条重要消息", "level": "critical", "volume": 8, "badge": 1, "sound": "bell", "icon": "https://example.com/icon.png", "group": "系统通知", "url": "https://example.com", "call": "1", "autoCopy": "1", "copy": "要复制的内容", "ciphertext": "加密内容", "isArchive": 1, "action": "none", "id": "12345", "delete": "1" } } ``` **注意:** - `receiver` 为设备专属的 Device Key(在 Bark 应用中获取) - `body` 为必需字段,不能为空 - `title` 为可选字段,如果为空则使用默认值 "通知" - 其他所有参数按照 [Bark 官方 API 文档](https://bark.day.app/#/tutorial) 格式传递 - 支持 Bark API 的所有参数:`subtitle`、`level`、`volume`、`badge`、`call`、`autoCopy`、`copy`、`sound`、`icon`、`group`、`ciphertext`、`isArchive`、`url`、`action`、`id`、`delete` 等 - 参数格式需符合 Bark API 要求(如 `isArchive` 应为数字 1/0,`call`、`autoCopy`、`delete` 应为字符串 "1" 等) ### 华为推送示例(HMS Core Push Kit) #### 方式一:使用完整的 message 对象 ```json { "channelType": 10, "receiver": "device_token_1,device_token_2", "data": { "message": { "android": { "notification": { "title": "通知标题", "body": "通知内容", "click_action": { "type": 3, "intent": "intent://com.example.app/detail?id=123" }, "badge": { "add_num": 1, "class": "com.example.app.MainActivity" }, "sound": "default" } }, "token": ["device_token_1", "device_token_2"] }, "validate_only": false } } ``` #### 方式二:使用简化的参数 ```json { "channelType": 10, "receiver": "device_token_1,device_token_2", "data": { "title": "通知标题", "content": "通知内容", "clickActionType": "3", "intent": "intent://com.example.app/detail?id=123", "badgeClass": "com.example.app.MainActivity", "badgeNum": 1, "sound": "default" } } ``` **注意:** - `receiver` 为设备 Token,多个用逗号或分号分隔 - 也可以使用 `deviceTokens` 字段(数组或逗号分隔的字符串) - 华为推送使用新版 HMS Core API(v1) - AccessToken 自动缓存,有效期 1 小时,提前 10 分钟刷新 - `clickActionType`:1=打开应用,2=打开 URL,3=打开 Intent - `intent`:Intent URI,用于打开应用内指定页面 ### 小米推送示例(Mi Push) #### 使用 regid 推送 ```json { "channelType": 11, "receiver": "regid1,regid2", "data": { "title": "通知标题", "description": "通知内容", "notifyType": "-1", "passThrough": "0", "packageName": "com.example.app", "timeToLive": "86400", "payload": "{\"key\":\"value\"}" } } ``` #### 使用 alias 推送 ```json { "channelType": 11, "receiver": "alias1,alias2", "data": { "pushType": "alias", "title": "通知标题", "description": "通知内容", "notifyType": "-1", "passThrough": "0" } } ``` **注意:** - `receiver` 为 regid 或 alias,多个用逗号或分号分隔 - 也可以使用 `deviceTokens` 字段(数组或逗号分隔的字符串) - `pushType`:`regid`(默认)或 `alias` - `passThrough`:`0`=通知栏消息,`1`=透传消息 - `notifyType`:通知类型,`-1` 表示使用默认值 - `description` 为必需字段,不能为空 ### Vivo 推送示例 #### 基础示例 ```json { "channelType": 12, "receiver": "regid_here", "data": { "title": "通知标题", "content": "通知内容", "notifyType": 4, "timeToLive": 86400, "skipType": 1, "networkType": -1, "classification": 1, "requestId": "optional_request_id" } } ``` **注意:** - `receiver` 为 regId(设备注册 ID) - 也可以使用 `regId` 字段覆盖 receiver - `content` 为必需字段,不能为空 - `notifyType`:通知类型,默认 4 - `timeToLive`:消息有效期(秒),默认 24 小时 - `skipType`:跳过类型,默认 1 - `networkType`:网络类型,-1 表示不限制 - `classification`:消息分类,默认 1 - AuthToken 自动缓存,有效期 1 小时,提前 10 分钟刷新 ### OPPO 推送示例 #### 基础示例 ```json { "channelType": 13, "receiver": "regid_here", "data": { "title": "通知标题", "content": "通知内容", "targetType": 2, "channelId": "default_channel", "skipType": 1, "pushTimeType": 0, "pushTime": 0, "duration": 0 } } ``` **注意:** - `receiver` 为 targetValue(regId、别名或标签) - 也可以使用 `targetValue` 或 `regId` 字段覆盖 receiver - `content` 为必需字段,不能为空 - `targetType`:1=全部,2=regId,3=别名,4=标签,默认 2 - `channelId`:通知渠道 ID(可选) - `skipType`、`pushTimeType`、`pushTime`、`duration` 为可选参数 - AuthToken 自动缓存,有效期 1 小时,提前 10 分钟刷新 ## 通道类型 - `channelType: 1` - 微信模板消息 - `channelType: 2` - MessagePusher - `channelType: 3` - 阿里云短信 - `channelType: 4` - 腾讯云短信 - `channelType: 5` - 邮件发送(SMTP) - `channelType: 6` - Telegram Bot 推送 - `channelType: 7` - Bark 推送 - `channelType: 8` - Apple 推送(APNs) - `channelType: 9` - Google 推送(FCM) - `channelType: 10` - 华为推送(HMS Core Push Kit) - `channelType: 11` - 小米推送(Mi Push) - `channelType: 12` - Vivo 推送 - `channelType: 13` - OPPO 推送 ## Apple 推送配置说明 ### 获取 Apple Push Notification 证书 1. 登录 [Apple Developer](https://developer.apple.com/) 2. 进入 **Certificates, Identifiers & Profiles** 3. 创建 **Key**,下载 `.p8` 文件 4. 记录 **Key ID**(10 位字符) 5. 记录 **Team ID**(10 位字符,在 Membership 页面查看) ### 配置项说明 - **P8PrivateKey**: P8 私钥文件内容(完整 PEM 格式,包括 BEGIN/END 标记) - **P8PrivateKeyId**: Key ID(10 位字符) - **TeamId**: Team ID(10 位字符) - **AppBundleIdentifier**: 应用的 Bundle Identifier(如:`com.example.app`) - **ServerType**: 服务器类型,`development` 或 `production`,默认 `production` ### 注意事项 - P8 私钥需要保持完整的 PEM 格式,包括换行符 - 确保 Bundle Identifier 与应用的 Bundle ID 一致 - 开发环境使用 `development`,生产环境使用 `production` ## Google 推送配置说明 ### 获取 FCM Server Key 1. 登录 [Firebase Console](https://console.firebase.google.com/) 2. 选择项目,进入 **项目设置** → **服务账号** 3. 点击 **生成新的私钥**,下载 JSON 文件 4. 或者使用 **Cloud Messaging** → **服务器密钥**(旧版 API) ### 配置项说明 - **ServerKey**: FCM Server Key(服务器密钥) - **SenderId**: FCM Sender ID(可选,通常不需要) ### 注意事项 - FCM Server Key 具有发送推送的权限,请妥善保管 - 确保应用已正确配置 Firebase SDK ## 微信推送配置说明 ### 获取微信公众号凭证 1. 登录 [微信公众平台](https://mp.weixin.qq.com/) 2. 进入 **开发** → **基本配置** 3. 获取 **AppID** 和 **AppSecret** 4. 配置 **服务器配置**(如需要接收消息) ### 配置项说明 - **AppId**: 微信公众号 AppID - **AppSecret**: 微信公众号 AppSecret ### 模板消息申请 1. 进入 **功能** → **模板消息** 2. 选择模板或申请新模板 3. 获取模板 ID(`template_id`) ### 技术实现 - **轻量级实现**:直接调用微信官方 API,无需第三方库 - **自动缓存**:Access Token 自动缓存,有效期 2 小时,提前 5 分钟刷新 - **支持功能**: - 模板消息发送 - 网页跳转(`url`) - 小程序跳转(`miniprogram`) - 自定义颜色和内容 ## Telegram Bot 配置说明 ### 获取 Bot Token 1. 在 Telegram 中搜索 `@BotFather` 2. 发送 `/newbot` 创建新机器人 3. 按提示设置机器人名称和用户名 4. 获取 Bot Token ### 配置项说明 - **BotToken**: Telegram Bot Token(从 @BotFather 获取) ### 获取 Chat ID #### 方法一:获取个人用户 Chat ID(最简单) 1. 在 Telegram 中搜索并打开 `@userinfobot` 或 `@getidsbot` 2. 发送任意消息(如 `/start` 或 `hello`) 3. Bot 会返回你的 **User ID**,这就是你的个人 Chat ID - 示例:`123456789`(通常是 9-10 位数字) #### 方法二:获取群组 Chat ID 1. 将你的 Bot 添加到群组 2. 在群组中发送一条消息(任意内容) 3. 调用 Telegram Bot API 获取更新: ```http GET https://api.telegram.org/bot