使用 Golang 发送钉钉个人消息:完整示例代码及解析

本文将详细介绍如何使用 Golang 发送钉钉个人消息,并提供完整示例代码和关键步骤解析,帮助您快速上手。

准备工作

  1. 创建钉钉应用:在钉钉开放平台创建您的应用,并获取到应用的 AppKeyAppSecret
  2. 获取用户 ID:获取您要发送消息的钉钉用户的 UserID

代码示例

package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	appKey    = "YOUR_APP_KEY"
	appSecret = "YOUR_APP_SECRET"
)

type DingTalkResponse struct {
	Errcode int    `json:"errcode"`
	Errmsg  string `json:"errmsg"`
}

func main() {
	accessToken, err := getAccessToken()
	if err != nil {
		fmt.Println("Failed to get access token:", err)
		return
	}

	err = sendTextMessage(accessToken, "dingtalk_user_id", "Hello, DingTalk!")
	if err != nil {
		fmt.Println("Failed to send text message:", err)
		return
	}

	fmt.Println("Text message sent successfully!")
}

func getAccessToken() (string, error) {
	timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10)
	sign := sign(timestamp)

	apiURL := "https://oapi.dingtalk.com/gettoken"
	query := url.Values{}
	query.Set("appkey", appKey)
	query.Set("timestamp", timestamp)
	query.Set("sign", sign)

	resp, err := http.Get(apiURL + "?" + query.Encode())
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var dingTalkResponse DingTalkResponse
	err = json.Unmarshal(body, &dingTalkResponse)
	if err != nil {
		return "", err
	}

	if dingTalkResponse.Errcode != 0 {
		return "", fmt.Errorf("error: %s", dingTalkResponse.Errmsg)
	}

	return dingTalkResponse.Errmsg, nil
}

func sendTextMessage(accessToken, userID, content string) error {
	apiURL := "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2"

	type Message struct {
		AgentID     int    `json:"agent_id"`
		UserID      string `json:"userid"`
		Msg         map[string]interface{} `json:"msg"`
	}

	msg := make(map[string]interface{})
	msg["msgtype"] = "text"
	msg["text"] = map[string]string{"content": content}

	message := Message{
		AgentID:     0, // 设置为0表示使用应用的默认配置
		UserID:      userID,
		Msg:         msg,
	}

	body, err := json.Marshal(message)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", apiURL+"?access_token="+accessToken, bytes.NewReader(body))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var dingTalkResponse DingTalkResponse
	err = json.Unmarshal(respBody, &dingTalkResponse)
	if err != nil {
		return err
	}

	if dingTalkResponse.Errcode != 0 {
		return fmt.Errorf("error: %s", dingTalkResponse.Errmsg)
	}

	return nil
}

func sign(timestamp string) string {
	stringToSign := fmt.Sprintf("%s\n%s", timestamp, appSecret)
	hmac256 := hmac.New(sha256.New, []byte(appSecret))
	hmac256.Write([]byte(stringToSign))
	signature := base64.StdEncoding.EncodeToString(hmac256.Sum(nil))
	return url.QueryEscape(signature)
}

代码解析:

  1. 获取 Access Token:

    • 使用 getAccessToken 函数获取访问令牌。
    • 函数首先生成时间戳和签名,然后构建请求 URL,并使用 HTTP GET 方法发送请求。
    • 解析响应内容,检查 errcode 是否为 0,如果成功则返回 Access Token。
  2. 发送文本消息:

    • 使用 sendTextMessage 函数发送文本消息。
    • 函数首先构建 JSON 格式的消息体,包含 agent_iduseridmsg 信息。
    • 使用 HTTP POST 方法发送消息,并解析响应内容,检查 errcode 是否为 0,如果成功则表示消息发送成功。
  3. 签名:

    • 使用 sign 函数生成请求签名。
    • 函数使用 HMACSHA256 算法对时间戳和 AppSecret 进行签名,并对结果进行 base64 编码和 URL 编码。

注意:

  • 将代码中的 YOUR_APP_KEYYOUR_APP_SECRET 替换为您的实际值。
  • dingtalk_user_id 替换为目标用户的实际用户 ID。
  • 确保您的应用具有发送个人消息的权限。

代码运行

  1. 保存代码为 main.go 文件。
  2. 运行 go run main.go 命令。

如果一切配置正确,您应该会收到一条来自钉钉的测试消息。

更多功能:

钉钉开放平台提供了丰富的 API 接口,您可以根据需要使用不同的接口发送不同类型的消息,例如图片、链接、markdown 文本等。详细 API 文档请参考 钉钉开放平台文档

希望本文能够帮助您快速上手 Golang 发送钉钉个人消息功能。如果您有任何问题,欢迎在评论区留言讨论。


原文地址: https://www.cveoy.top/t/topic/pKCv 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录