代码拉取完成,页面将自动刷新
package dingtalk
import (
"context"
"fmt"
"net/http"
)
// SendWebhookActionCardMessage 发送 ActionCard 消息(单按钮模式)
// 参数:
// - ctx: 上下文
// - webhook: Webhook 地址
// - title: 首屏会话透出的展示内容
// - text: Markdown 格式的消息内容
// - singleTitle: 按钮标题
// - singleURL: 按钮跳转链接
// - btnOrientation: 按钮排列方式,"0"-竖直排列,"1"-横向排列(可选,默认"0")
// - at: @人信息(可选,注意:钉钉官方actionCard类型不支持@人,此参数为扩展预留)
//
// 返回:
// - error: 发送失败时返回错误信息
func (c *Client) SendWebhookActionCardMessage(ctx context.Context, webhook, title, text, singleTitle, singleURL string, btnOrientation ...string) error {
return c.sendWebhookActionCardMessageWithAt(ctx, webhook, title, text, singleTitle, singleURL, nil, btnOrientation...)
}
// sendWebhookActionCardMessageWithAt 发送 ActionCard 消息(单按钮模式,支持@人)
// 内部方法,支持@人功能
func (c *Client) sendWebhookActionCardMessageWithAt(ctx context.Context, webhook, title, text, singleTitle, singleURL string, at *WebhookAt, btnOrientation ...string) error {
if webhook == "" {
return fmt.Errorf("webhook 不能为空")
}
if title == "" {
return fmt.Errorf("title 不能为空")
}
if text == "" {
return fmt.Errorf("text 不能为空")
}
if singleTitle == "" {
return fmt.Errorf("singleTitle 不能为空")
}
if singleURL == "" {
return fmt.Errorf("singleURL 不能为空")
}
orientation := "0"
if len(btnOrientation) > 0 && btnOrientation[0] != "" {
orientation = btnOrientation[0]
}
// 构造消息体
msgBody := WebhookActionCardMessage{
MsgType: "actionCard",
ActionCard: &WebhookActionCardContent{
Title: title,
Text: text,
SingleTitle: singleTitle,
SingleURL: singleURL,
BtnOrientation: orientation,
},
At: at,
}
// 记录发送日志
c.Log.Debugw("准备发送 ActionCard 消息(单按钮)",
"webhook_url", webhook,
"title", title,
"text_length", len(text),
)
// 发送 HTTP POST 请求
resp := c.httpClient.Post(webhook).DataJs(msgBody).Do(ctx)
// 检查 HTTP 请求错误
if resp.Error() != nil {
c.Log.Errorw("Webhook HTTP 请求失败",
"error", resp.Error(),
"webhook_url", webhook,
)
return fmt.Errorf("HTTP请求失败: %w", resp.Error())
}
// 检查 HTTP 状态码
if resp.StatusCode() != http.StatusOK {
c.Log.Errorw("Webhook 请求返回非200状态码",
"status_code", resp.StatusCode(),
"webhook_url", webhook,
)
return fmt.Errorf("Webhook请求失败,状态码: %d", resp.StatusCode())
}
// 解析响应
var webhookResp WebhookResponse
if err := resp.Into(&webhookResp); err != nil {
c.Log.Errorw("解析 Webhook 响应失败",
"error", err,
"response_body", resp.Text(),
)
return fmt.Errorf("解析响应失败: %w", err)
}
// 检查业务错误码
if webhookResp.ErrCode != 0 {
c.Log.Errorw("Webhook 返回业务错误",
"errcode", webhookResp.ErrCode,
"errmsg", webhookResp.ErrMsg,
)
return fmt.Errorf("Webhook业务错误: [%d] %s", webhookResp.ErrCode, webhookResp.ErrMsg)
}
// 发送成功
c.Log.Infow("ActionCard 消息(单按钮)发送成功",
"title", title,
)
return nil
}
// SendWebhookActionCardMessageV2 发送 ActionCard 消息(多按钮模式)
// 参数:
// - ctx: 上下文
// - webhook: Webhook 地址
// - title: 首屏会话透出的展示内容
// - text: Markdown 格式的消息内容
// - btns: 按钮列表
// - btnOrientation: 按钮排列方式,"0"-竖直排列,"1"-横向排列(可选,默认"0")
//
// 返回:
// - error: 发送失败时返回错误信息
func (c *Client) SendWebhookActionCardMessageV2(ctx context.Context, webhook, title, text string, btns []*WebhookActionCardButton, btnOrientation ...string) error {
return c.sendWebhookActionCardMessageV2WithAt(ctx, webhook, title, text, btns, nil, btnOrientation...)
}
// sendWebhookActionCardMessageV2WithAt 发送 ActionCard 消息(多按钮模式,支持@人)
// 内部方法,支持@人功能
func (c *Client) sendWebhookActionCardMessageV2WithAt(ctx context.Context, webhook, title, text string, btns []*WebhookActionCardButton, at *WebhookAt, btnOrientation ...string) error {
if webhook == "" {
return fmt.Errorf("webhook 不能为空")
}
if title == "" {
return fmt.Errorf("title 不能为空")
}
if text == "" {
return fmt.Errorf("text 不能为空")
}
if len(btns) == 0 {
return fmt.Errorf("btns 不能为空")
}
orientation := "0"
if len(btnOrientation) > 0 && btnOrientation[0] != "" {
orientation = btnOrientation[0]
}
// 构造消息体
msgBody := WebhookActionCardMessage{
MsgType: "actionCard",
ActionCard: &WebhookActionCardContent{
Title: title,
Text: text,
BtnOrientation: orientation,
Btns: btns,
},
At: at,
}
// 记录发送日志
c.Log.Debugw("准备发送 ActionCard 消息(多按钮)",
"webhook_url", webhook,
"title", title,
"text_length", len(text),
"btns_count", len(btns),
)
// 发送 HTTP POST 请求
resp := c.httpClient.Post(webhook).DataJs(msgBody).Do(ctx)
// 检查 HTTP 请求错误
if resp.Error() != nil {
c.Log.Errorw("Webhook HTTP 请求失败",
"error", resp.Error(),
"webhook_url", webhook,
)
return fmt.Errorf("HTTP请求失败: %w", resp.Error())
}
// 检查 HTTP 状态码
if resp.StatusCode() != http.StatusOK {
c.Log.Errorw("Webhook 请求返回非200状态码",
"status_code", resp.StatusCode(),
"webhook_url", webhook,
)
return fmt.Errorf("Webhook请求失败,状态码: %d", resp.StatusCode())
}
// 解析响应
var webhookResp WebhookResponse
if err := resp.Into(&webhookResp); err != nil {
c.Log.Errorw("解析 Webhook 响应失败",
"error", err,
"response_body", resp.Text(),
)
return fmt.Errorf("解析响应失败: %w", err)
}
// 检查业务错误码
if webhookResp.ErrCode != 0 {
c.Log.Errorw("Webhook 返回业务错误",
"errcode", webhookResp.ErrCode,
"errmsg", webhookResp.ErrMsg,
)
return fmt.Errorf("Webhook业务错误: [%d] %s", webhookResp.ErrCode, webhookResp.ErrMsg)
}
// 发送成功
c.Log.Infow("ActionCard 消息(多按钮)发送成功",
"title", title,
"btns_count", len(btns),
)
return nil
}
// SendWebhookActionCardMessageV3 发送 ActionCard 消息(使用请求对象)
// 参数:
// - ctx: 上下文
// - req: ActionCard 消息请求参数
//
// 返回:
// - error: 发送失败时返回错误信息
func (c *Client) SendWebhookActionCardMessageV3(ctx context.Context, req *SendActionCardRequest) error {
if req == nil {
return fmt.Errorf("请求参数不能为空")
}
if req.Webhook == "" {
return fmt.Errorf("webhook 不能为空")
}
if req.Title == "" {
return fmt.Errorf("title 不能为空")
}
if req.Text == "" {
return fmt.Errorf("text 不能为空")
}
// 构造@人信息(注意:钉钉官方actionCard类型不支持@人,此字段为扩展预留)
var at *WebhookAt
if len(req.AtMobiles) > 0 || len(req.AtUserIds) > 0 || req.IsAtAll {
at = &WebhookAt{
AtMobiles: req.AtMobiles,
AtUserIds: req.AtUserIds,
IsAtAll: req.IsAtAll,
}
}
// 判断是单按钮模式还是多按钮模式
if req.SingleTitle != "" && req.SingleURL != "" {
// 单按钮模式
return c.sendWebhookActionCardMessageWithAt(ctx, req.Webhook, req.Title, req.Text,
req.SingleTitle, req.SingleURL, at, req.BtnOrientation)
} else if len(req.Btns) > 0 {
// 多按钮模式
return c.sendWebhookActionCardMessageV2WithAt(ctx, req.Webhook, req.Title, req.Text,
req.Btns, at, req.BtnOrientation)
}
return fmt.Errorf("必须指定单按钮(SingleTitle+SingleURL)或多按钮(Btns)")
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。