# V1 API 文档 V1 API 提供基于任务的消息推送接口,支持多渠道、多格式发送。 ::: tip 💡 推荐使用 V2 API(模板) 对于**所有新项目**,我们强烈推荐使用 [V2 API(模板)](/api/v2): - ✅ **内容复用** - 模板可以在多个场景中复用,无需每次传递完整内容 - ✅ **完全动态** - 通过占位符可以实现完全动态内容(甚至可以只用一个占位符) - ✅ **统一管理** - 在管理后台统一管理消息模板,便于维护 - ✅ **版本控制** - 模板内容修改不影响 API 调用代码 - ✅ **更安全** - 使用加密 Token,不暴露模板 ID ::: warning 关于 V1 API V1 API 仅为兼容历史数据而保留,不推荐在新项目中使用。后续的功能优化和维护重点都在 V2 API(模板)上。 ::: ## 接口地址 ``` POST /api/v1/message/send ``` ## 请求参数 ### 基本参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | token | string | 是 | 推送令牌(加密),在管理后台查看 | | task_id | string | 否 | 任务ID(明文),与 token 二选一 | | title | string | 是 | 消息标题 | | text | string | 否 | 纯文本格式内容 | | html | string | 否 | HTML 格式内容 | | markdown | string | 否 | Markdown 格式内容 | ::: tip 提示 - `token` 和 `task_id` 二选一,推荐使用加密的 `token` - `text`、`html`、`markdown` 至少提供一种格式 - 多种格式可以同时提供,系统会根据渠道自动选择 ::: ### @提醒参数(可选) | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | at_mobiles | array | 否 | @手机号列表,如 `["13800138000", "13900139000"]` | | at_userids | array | 否 | @用户ID列表,如 `["user001", "user002"]` | | at_all | boolean | 否 | 是否@所有人,默认 `false` | ::: warning 注意 @提醒功能仅在支持的渠道(钉钉、企业微信)中生效。 ::: ### 动态接收者参数(可选)🆕 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | recipients | array | 否 | 动态接收者列表,如 `["user1@example.com", "user2@example.com"]` | ::: tip 群发模式 动态接收者功能允许在 API 调用时指定接收者列表,实现群发功能。 **支持的渠道:** - ✅ **邮件** - 支持多个收件人,实现邮件群发 - ✅ **微信公众号** - 支持多个 OpenID,实现公众号群发 **使用条件:** 1. 任务实例必须配置为"动态接收者模式" 2. 一个任务只能配置一个动态接收实例 3. 动态接收实例不能与固定接收实例混合使用 **配置方式:** 在任务编辑页面,添加实例时勾选"动态接收者模式",此时无需配置固定接收者。 **注意事项:** - 如果任务配置了动态接收实例,`recipients` 参数为必填 - 不支持动态接收的渠道会忽略此参数 - 建议控制接收者数量,避免触发渠道限流 ::: ## 请求示例 ### 基本示例(纯文本) ```json { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "系统通知", "text": "Hello World!" } ``` ### 多格式示例 ```json { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "系统通知", "text": "您好,系统检测到异常登录。", "html": "
您好,系统检测到异常登录。
", "markdown": "## 系统通知\n\n您好,系统检测到**异常登录**。" } ``` ### 带@提醒示例 ```json { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "紧急告警", "text": "服务器CPU使用率超过90%,请及时处理!", "markdown": "## 紧急告警\n\n服务器CPU使用率超过**90%**,请及时处理!", "at_mobiles": ["13800138000", "13900139000"], "at_all": false } ``` ### 动态接收者示例(群发)🆕 ```json { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "系统维护通知", "text": "系统将于今晚22:00进行维护,预计持续2小时。", "html": "系统将于今晚22:00进行维护,预计持续2小时。
", "recipients": [ "user1@example.com", "user2@example.com", "user3@example.com" ] } ``` ### cURL 示例 ```bash curl -X POST http://your-domain/api/v1/message/send \ -H "Content-Type: application/json" \ -d '{ "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "系统通知", "text": "Hello World!" }' ``` ## 响应格式 ### 成功响应 ```json { "code": 200, "msg": "success", "data": { "status": "sent" } } ``` ### 失败响应 ```json { "code": 400, "msg": "error message", "data": null } ``` ## 获取 Token 1. 登录 Message Nest 管理后台 2. 进入"发送任务"页面 3. 创建新的发送任务 4. 配置推送渠道(邮件、钉钉、企业微信等) 5. 保存后获得推送令牌(Token) ## 消息格式优先级 V1 API 支持三种消息格式,系统会根据任务实例配置的格式类型自动选择对应的内容。 ### 格式选择规则 当任务实例配置了特定格式类型时,系统按以下优先级选择内容: | 实例配置格式 | 优先级顺序 | 说明 | |------------|-----------|------| | **HTML** | html → markdown → text | 优先使用 HTML,其次 Markdown,最后纯文本 | | **Markdown** | markdown → text → html | 优先使用 Markdown,其次纯文本,最后 HTML | | **Text** | text → markdown → html | 优先使用纯文本,其次 Markdown,最后 HTML | ### 示例说明 **场景 1:邮件渠道(配置为 HTML 格式)** ```json { "text": "纯文本内容", "html": "您的订单已发货
订单号:20241206001
", "markdown": "## 订单通知\n\n您的订单已发货\n\n订单号:**20241206001**" } ``` ### 2. 合理使用@提醒 只在需要紧急通知时使用@提醒: ```json { "token": "...", "title": "紧急告警", "text": "生产环境出现严重问题", "at_mobiles": ["13800138000"], // 只@相关负责人 "at_all": false // 避免@所有人 } ``` ### 3. 错误处理 ```python import requests import json def send_message(token, title, text): url = "http://your-domain/api/v1/message/send" data = { "token": token, "title": title, "text": text } try: response = requests.post(url, json=data, timeout=10) result = response.json() if result['code'] == 200: print("发送成功") else: print(f"发送失败:{result['msg']}") except Exception as e: print(f"请求异常:{e}") ``` ## 错误码说明 | 错误码 | 说明 | |--------|------| | 200 | 成功 | | 400 | 请求参数错误 | | 401 | 未授权 | | 404 | Token不存在 | | 500 | 服务器内部错误 | ## 常见问题 ### Q: V1 和 V2 API 有什么区别?应该选择哪个? **A:** | 特性 | V1 API(任务) | V2 API(模板)⭐ 推荐 | |------|--------------|-------------------| | **内容定义** | API 调用时传递 | 预定义在模板中 | | **动态内容** | 完全动态 | 通过占位符替换 | | **内容复用** | 每次都要传递完整内容 | 模板可复用 | | **维护成本** | 修改内容需要改代码 | 只需修改模板 | | **适用场景** | 完全动态、不重复的内容 | 有固定格式的通知消息 | **推荐使用 V2 API(模板)的原因:** 1. **提高开发效率** - 一次定义模板,多处使用 2. **降低维护成本** - 内容修改无需改代码 3. **统一管理** - 所有消息模板集中管理 4. **更好的协作** - 运营人员可以直接修改模板内容 5. **版本控制** - 模板支持启用/禁用,方便灰度发布 6. **完全动态** - 通过占位符同样可以实现完全动态内容 ::: warning V1 API 的定位 V1 API 仅为兼容历史数据而保留,**不推荐在任何新项目中使用**。即使是完全动态的内容,也可以通过模板 + 占位符的方式实现,且更易于后期维护。 后续的功能优化和维护重点都在 V2 API(模板)上。 ::: ### Q: 如何选择使用哪种格式? **A:** 根据渠道特性选择: - **邮件**:推荐 HTML,视觉效果好 - **钉钉/企业微信**:推荐 Markdown,支持富文本 - **通用**:使用 Text,兼容性最好 - **多渠道**:同时提供多种格式,让系统自动选择 ### Q: @提醒不生效怎么办? **A:** 检查以下几点: 1. 渠道是否支持@提醒(仅钉钉、企业微信支持) 2. 机器人是否有@权限 3. 手机号或用户ID格式是否正确 4. 参数名称是否正确(`at_mobiles`、`at_userids`、`at_all`) ### Q: 可以只发送 HTML 格式吗? **A:** 可以,但建议同时提供 text 格式作为备选,确保不支持 HTML 的渠道也能正常发送。 ### Q: Token 和 task_id 有什么区别? **A:** - **token**:加密的任务标识,更安全,推荐使用 - **task_id**:明文的任务ID,不推荐在生产环境使用 ## 各语言调用示例 本节提供各种编程语言的完整调用示例代码。 ### cURL ```bash curl -X POST --location 'http://127.0.0.1:8000/api/v1/message/send' \ --header 'Content-Type: application/json' \ --data '{ "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "message title", "text": "Hello World!" }' ``` ### Python ```python import requests headers = { 'Content-Type': 'application/json', } json_data = { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "message title", "text": "Hello World!" } response = requests.post( 'http://127.0.0.1:8000/api/v1/message/send', headers=headers, json=json_data ) print("response:", response.json()) ``` **安装依赖:** ```bash pip install requests ``` ### Go ```go package main import ( "fmt" "io" "log" "net/http" "strings" ) func main() { client := &http.Client{} var data = strings.NewReader(`{ "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "message title", "text": "Hello World!" }`) req, err := http.NewRequest("POST", "http://127.0.0.1:8000/api/v1/message/send", data) if err != nil { log.Fatal(err) } req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() bodyText, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", bodyText) } ``` ### Java ```java import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; public class MessageNestExample { public static void main(String[] args) throws IOException, InterruptedException { HttpClient client = HttpClient.newBuilder() .followRedirects(HttpClient.Redirect.NORMAL) .build(); String jsonData = """ { "token": "a3541c2f0d3e1b4a5c6d7e8f9a0b1c2d3e", "title": "message title", "text": "Hello World!" } """; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://127.0.0.1:8000/api/v1/message/send")) .POST(BodyPublishers.ofString(jsonData)) .setHeader("Content-Type", "application/json") .build(); HttpResponse