Skip to content

Instantly share code, notes, and snippets.

@flydo
Created October 24, 2023 11:44
Show Gist options
  • Save flydo/00e2c4141060610bc814ae36f536c455 to your computer and use it in GitHub Desktop.
Save flydo/00e2c4141060610bc814ae36f536c455 to your computer and use it in GitHub Desktop.
飞书/钉钉群机器人通知发送的案例(Go、Shell)https://www.idev.top/d/385
/**
# 飞书/钉钉群机器人通知发送的案例
1. 创建文件夹 `test`
2. 将下述代码粘贴至 test 目录下的 `main.go` 文件中
3. 执行 `go mod tidy test`,创建 `module` 方式
4. 使用 `go run main.go -u "https://open.feishu.cn/xxx" -s "Secret" -m "Message" -t 1234567890` 方式发送通知消息(-t 部分可省略)
5. 执行 `go build` 生成 `test` 可执行文件
*/
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
"log"
)
var (
webhookUrl string
message string
secret string
ts int64
)
func sendMsg(apiUrl, msg string) {
// json
contentType := "application/json"
if ts == 0 {
ts = time.Now().Unix()
}
var sign string
// data
sendData1 := `{
"msg_type": "text",
"content": {"text": "消息通知: %s "},
"sign": "%s",
"timestamp": %d
}`
sendData2 := `{
"msgtype": "text",
"text": {
"content": "消息通知: %s "
},
"at": {
"isAtAll": false
}
}`
var sendData string
if strings.HasPrefix(apiUrl, "https://oapi.dingtalk.com") {
sendData = sendData2
if ts <= 10e9 {
ts *= 1000
}
sign, _ = GenSign(secret, ts, 2)
sendData = fmt.Sprintf(sendData2, message)
apiUrl = fmt.Sprintf("%s&timestamp=%d&sign=%s", apiUrl, ts, sign)
} else if strings.HasPrefix(apiUrl, "https://open.feishu.cn") {
sign, _ = GenSign(secret, ts, 1)
sendData = fmt.Sprintf(sendData1, message, sign, ts)
} else {
fmt.Printf("此方式(%s)不支持\n", apiUrl)
return
}
fmt.Printf(`%s
%s
timestamp: %d
secret: %s
sign: %s
`, apiUrl, sendData, ts, secret, sign)
// request
result, err := http.Post(apiUrl, contentType, strings.NewReader(sendData))
if err != nil {
fmt.Printf("post failed, err:%v\n", err)
return
}
defer result.Body.Close()
rspBody, err := ioutil.ReadAll(result.Body)
if err != nil {
log.Fatalf("ReadAll failed, reqBody: %s, err: %v\n", rspBody, err)
return
}
fmt.Println("结果:" + string(rspBody))
}
func main() {
flag.StringVar(&webhookUrl, "u", "", "飞书/钉钉webhook地址")
flag.StringVar(&secret, "s", "", "密钥")
flag.StringVar(&message, "m", "", "需要发送的消息内容")
flag.Int64Var(&ts, "t", 0, "时间戳")
flag.Parse()
//flag.Usage()
sendMsg(webhookUrl, message)
}
// GenSign 签名
// mode: 1.飞书 2.钉钉
func GenSign(secret string, timestamp int64, mode int) (string, error) {
stringToSign := fmt.Sprintf("%d\n%s", timestamp, secret)
var data []byte
var signStr string
if mode == 1 {
signStr = stringToSign
} else {
signStr = secret
data = []byte(stringToSign)
}
h := hmac.New(sha256.New, []byte(signStr))
_, err := h.Write(data)
if err != nil {
return "", err
}
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
return signature, nil
}
#!/bin/sh
#
# sh main.sh -u "https://open.feishu.cn/xxx" -s "Secret" -m "Message" -t 1234567890 (-t 部分可省略)
#
get_vars() {
while [ $# -gt 0 ]
do
case "${1}" in
# 需要发送的消息内容
-m | --message )
MESSAGE="${2}"
shift
;;
# 钉钉webhook地址
-u | --url )
URL="${2}"
shift
;;
# 密钥
-s | --secret )
SECRET="${2}"
shift
;;
# 时间戳(可省略)
-t | --timestamp )
TS="${2}"
shift
;;
esac
shift
done
}
send_msg() {
[[ -n "${TS}" ]] || TS="$(date +%s)"
sendData1='{
"msg_type": "text",
"content": {"text": "消息通知: %s "},
"sign": "%s",
"timestamp": %d
}'
sendData2='{
"msgtype": "text",
"text": {
"content": "消息通知: %s "
},
"at": {
"isAtAll": false
}
}'
if [[ -n $(echo "${URL}" | grep "oapi.dingtalk.com") ]]; then
[[ ${#TS} -lt 11 ]] && TS="${TS}000"
get_sign 2
semd_msg=$(printf "${sendData2}" ${MESSAGE} )
URL=$(printf "${URL}&timestamp=%s&sign=%s" ${TS} ${SIGN})
elif [[ -n $(echo "${URL}" | grep "open.feishu.cn") ]]; then
get_sign 1
semd_msg=$(printf "${sendData1}" ${MESSAGE} ${SIGN} ${TS})
else
printf "此方式(%s)不支持\n" "${URL}"
return
fi
# echo "${semd_msg}"
# printf '%s\ntimestamp: %s\nsecret: %s\nsign: %s\n' ${URL} ${TS} ${SECRET} ${SIGN}
curl -XPOST -s -L "${URL}" -H "Content-Type:application/json" -H "charset:utf-8" -d "${semd_msg}"
}
get_sign() {
mode="${1}"
string_to_sign="${TS}\n${SECRET}"
data=""
if [[ "${mode}" = "1" ]]; then
sign_str="${string_to_sign}"
elif [[ "${mode}" = "2" ]]; then
sign_str="${SECRET}"
data="${string_to_sign}"
else
printf "此方式(%s)不支持\n" "${URL}"
exit 1
fi
printf "${sign_str}" > ./key.dat
# printf "${data}"
SIGN=$(printf "${data}" | openssl dgst -sha256 -hmac "$(cat ./key.dat)" -binary | base64)
#echo $SIGN
rm -rf ./key.dat
}
main() {
get_vars "$@"
send_msg
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment