✨ 初始化项目
This commit is contained in:
parent
858ee66482
commit
05b77d99c7
77
.gitignore
vendored
77
.gitignore
vendored
@ -1,7 +1,5 @@
|
||||
# ---> Go
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Go template
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
@ -18,6 +16,73 @@
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
.idea/
|
||||
|
134
bot.go
Normal file
134
bot.go
Normal file
@ -0,0 +1,134 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
const (
|
||||
defaultWebHookUrlTemplate = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnsupportedMessage = errors.New("尚不支持的消息类型")
|
||||
)
|
||||
|
||||
type WxWorkBot struct {
|
||||
Key string
|
||||
WebHookUrl string
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
// 创建一个新的机器人实例
|
||||
func New(botKey string) *WxWorkBot {
|
||||
bot := WxWorkBot{
|
||||
Key: botKey,
|
||||
// 直接拼接出接口 URL
|
||||
WebHookUrl: fmt.Sprintf(defaultWebHookUrlTemplate, botKey),
|
||||
// 默认 5 秒超时
|
||||
Client: &http.Client{Timeout: 5 * time.Second},
|
||||
}
|
||||
return &bot
|
||||
}
|
||||
|
||||
// 发送消息,允许的参数类型:Text、Markdown、Image、News
|
||||
func (bot *WxWorkBot) Send(msg interface{}) error {
|
||||
msgBytes, err := marshalMessage(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
webHookUrl := bot.WebHookUrl
|
||||
if len(webHookUrl) == 0 {
|
||||
webHookUrl = fmt.Sprintf(defaultWebHookUrlTemplate, bot.Key)
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodPost, webHookUrl, bytes.NewBuffer(msgBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := bot.Client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
defer resp.Body.Close()
|
||||
var wxWorkResp wxWorkResponse
|
||||
err = json.Unmarshal(body, &wxWorkResp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if wxWorkResp.ErrorCode != 0 && wxWorkResp.ErrorMessage != "" {
|
||||
return errors.New(string(body))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 防止 < > 等 HTML 字符在 json.marshal 时被 escape
|
||||
func marshal(msg interface{}) ([]byte, error) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
jsonEncoder := json.NewEncoder(buf)
|
||||
jsonEncoder.SetEscapeHTML(false)
|
||||
jsonEncoder.SetIndent("", "")
|
||||
err := jsonEncoder.Encode(msg)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// 将消息包装成企信接口要求的格式,返回 json bytes
|
||||
func marshalMessage(msg interface{}) ([]byte, error) {
|
||||
if text, ok := msg.(Text); ok {
|
||||
textMsg := textMessage{
|
||||
message: message{MsgType: "text"},
|
||||
Text: text,
|
||||
}
|
||||
return marshal(textMsg)
|
||||
}
|
||||
if textMsg, ok := msg.(textMessage); ok {
|
||||
textMsg.MsgType = "text"
|
||||
return marshal(textMsg)
|
||||
}
|
||||
if markdown, ok := msg.(Markdown); ok {
|
||||
markdownMsg := markdownMessage{
|
||||
message: message{MsgType: "markdown"},
|
||||
Markdown: markdown,
|
||||
}
|
||||
return marshal(markdownMsg)
|
||||
}
|
||||
if markdownMsg, ok := msg.(markdownMessage); ok {
|
||||
markdownMsg.MsgType = "markdown"
|
||||
return marshal(markdownMsg)
|
||||
}
|
||||
if image, ok := msg.(Image); ok {
|
||||
imageMsg := imageMessage{
|
||||
message: message{MsgType: "image"},
|
||||
Image: image,
|
||||
}
|
||||
return marshal(imageMsg)
|
||||
}
|
||||
if imageMsg, ok := msg.(imageMessage); ok {
|
||||
imageMsg.MsgType = "image"
|
||||
return marshal(imageMsg)
|
||||
}
|
||||
if news, ok := msg.(News); ok {
|
||||
newsMsg := newsMessage{
|
||||
message: message{MsgType: "news"},
|
||||
News: news,
|
||||
}
|
||||
return marshal(newsMsg)
|
||||
}
|
||||
if newsMsg, ok := msg.(newsMessage); ok {
|
||||
newsMsg.MsgType = "news"
|
||||
return marshal(newsMsg)
|
||||
}
|
||||
return nil, ErrUnsupportedMessage
|
||||
}
|
177
bot_test.go
Normal file
177
bot_test.go
Normal file
@ -0,0 +1,177 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getBotKey() string {
|
||||
return os.Getenv("WXWORK_BOT_KEY")
|
||||
}
|
||||
|
||||
func TestMarshalText(t *testing.T) {
|
||||
text := Text{
|
||||
Content: "广州今日天气:29度,大部分多云,降雨概率:60%",
|
||||
MentionedList: []string{"wangqing", "@all"},
|
||||
MentionedMobileList: []string{"13800001111", "@all"},
|
||||
}
|
||||
msgBytes, err := marshalMessage(text)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"text","text":{"content":"广州今日天气:29度,大部分多云,降雨概率:60%","mentioned_list":["wangqing","@all"],"mentioned_mobile_list":["13800001111","@all"]}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalTextMessage(t *testing.T) {
|
||||
textMsg := textMessage{
|
||||
Text: Text{
|
||||
Content: "广州今日天气:29度,大部分多云,降雨概率:60%",
|
||||
MentionedList: []string{"wangqing", "@all"},
|
||||
MentionedMobileList: []string{"13800001111", "@all"},
|
||||
},
|
||||
}
|
||||
msgBytes, err := marshalMessage(textMsg)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"text","text":{"content":"广州今日天气:29度,大部分多云,降雨概率:60%","mentioned_list":["wangqing","@all"],"mentioned_mobile_list":["13800001111","@all"]}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalMarkdown(t *testing.T) {
|
||||
markdown := Markdown{
|
||||
Content: "<font color=\"warning\">233</font>",
|
||||
}
|
||||
msgBytes, err := marshalMessage(markdown)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"markdown","markdown":{"content":"<font color=\"warning\">233</font>"}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalMarkdownMessage(t *testing.T) {
|
||||
markdownMsg := markdownMessage{
|
||||
Markdown: Markdown{
|
||||
Content: "<font color=\"warning\">233</font>",
|
||||
},
|
||||
}
|
||||
msgBytes, err := marshalMessage(markdownMsg)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"markdown","markdown":{"content":"<font color=\"warning\">233</font>"}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalImage(t *testing.T) {
|
||||
image := Image{
|
||||
Base64: "DATA",
|
||||
MD5: "MD5",
|
||||
}
|
||||
msgBytes, err := marshalMessage(image)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"image","image":{"base64":"DATA","md5":"MD5"}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalImageMessage(t *testing.T) {
|
||||
imageMsg := imageMessage{
|
||||
Image: Image{
|
||||
Base64: "DATA",
|
||||
MD5: "MD5",
|
||||
},
|
||||
}
|
||||
msgBytes, err := marshalMessage(imageMsg)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"image","image":{"base64":"DATA","md5":"MD5"}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalNews(t *testing.T) {
|
||||
news := News{
|
||||
Articles: []NewsArticle{
|
||||
{
|
||||
Title: "中秋节礼品领取",
|
||||
Description: "今年中秋节公司有豪礼相送",
|
||||
URL: "URL",
|
||||
PicURL: "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png",
|
||||
},
|
||||
},
|
||||
}
|
||||
msgBytes, err := marshalMessage(news)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"news","news":{"articles":[{"title":"中秋节礼品领取","description":"今年中秋节公司有豪礼相送","url":"URL","picurl":"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"}]}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalNewsMessage(t *testing.T) {
|
||||
newsMsg := newsMessage{
|
||||
News: News{
|
||||
Articles: []NewsArticle{
|
||||
{
|
||||
Title: "中秋节礼品领取",
|
||||
Description: "今年中秋节公司有豪礼相送",
|
||||
URL: "URL",
|
||||
PicURL: "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png",
|
||||
},
|
||||
}},
|
||||
}
|
||||
msgBytes, err := marshalMessage(newsMsg)
|
||||
assert.Nil(t, err)
|
||||
expected := `{"msgtype":"news","news":{"articles":[{"title":"中秋节礼品领取","description":"今年中秋节公司有豪礼相送","url":"URL","picurl":"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"}]}}`
|
||||
msg := strings.TrimSuffix(string(msgBytes), "\n")
|
||||
assert.Equal(t, expected, msg)
|
||||
}
|
||||
|
||||
func TestMarshalUnsupportedMessage(t *testing.T) {
|
||||
text := struct {
|
||||
Foo string
|
||||
}{
|
||||
Foo: "bar",
|
||||
}
|
||||
_, err := marshalMessage(text)
|
||||
assert.Equal(t, ErrUnsupportedMessage, err)
|
||||
}
|
||||
|
||||
func TestSendText(t *testing.T) {
|
||||
bot := New(getBotKey())
|
||||
err := bot.Send(Text{
|
||||
Content: "测试发送文本消息",
|
||||
MentionedList: []string{"wangqing", "@all"},
|
||||
MentionedMobileList: []string{"13800001111", "@all"},
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestSendWithInvalidBotKey(t *testing.T) {
|
||||
textMsg := textMessage{
|
||||
Text: Text{
|
||||
Content: "广州今日天气:29度,大部分多云,降雨概率:60%",
|
||||
MentionedList: []string{"wangqing", "@all"},
|
||||
MentionedMobileList: []string{"13800001111", "@all"},
|
||||
},
|
||||
}
|
||||
bot := New("这是一个错误的 BOT KEY")
|
||||
err := bot.Send(textMsg)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestWithCustomHttpClient(t *testing.T) {
|
||||
bot := WxWorkBot{
|
||||
Key: getBotKey(),
|
||||
Client: &http.Client{
|
||||
Timeout: 1 * time.Second,
|
||||
},
|
||||
}
|
||||
err := bot.Send(Text{
|
||||
Content: "广州今日天气:29度,大部分多云,降雨概率:60%",
|
||||
MentionedList: []string{"wangqing", "@all"},
|
||||
MentionedMobileList: []string{"13800001111", "@all"},
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/vimsucks/wxwork-bot-go
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/stretchr/testify v1.4.0
|
10
go.sum
Normal file
10
go.sum
Normal file
@ -0,0 +1,10 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
11
image.go
Normal file
11
image.go
Normal file
@ -0,0 +1,11 @@
|
||||
package wxworkbot
|
||||
|
||||
type imageMessage struct {
|
||||
message
|
||||
Image Image `json:"image"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
Base64 string `json:"base64"`
|
||||
MD5 string `json:"md5"`
|
||||
}
|
25
image_test.go
Normal file
25
image_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestImageMessage(t *testing.T) {
|
||||
jsonString := `
|
||||
{
|
||||
"msgtype": "image",
|
||||
"image": {
|
||||
"base64": "DATA",
|
||||
"md5": "MD5"
|
||||
}
|
||||
}
|
||||
`
|
||||
var imageMsg imageMessage
|
||||
err := json.Unmarshal([]byte(jsonString), &imageMsg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, imageMsg.MsgType, "image")
|
||||
assert.Equal(t, imageMsg.Image.Base64, "DATA")
|
||||
assert.Equal(t, imageMsg.Image.MD5, "MD5")
|
||||
}
|
10
markdown.go
Normal file
10
markdown.go
Normal file
@ -0,0 +1,10 @@
|
||||
package wxworkbot
|
||||
|
||||
type markdownMessage struct {
|
||||
message
|
||||
Markdown Markdown `json:"markdown"`
|
||||
}
|
||||
|
||||
type Markdown struct {
|
||||
Content string `json:"content"`
|
||||
}
|
23
markdown_test.go
Normal file
23
markdown_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMarkdownMessage(t *testing.T) {
|
||||
jsonString := `
|
||||
{
|
||||
"msgtype": "markdown",
|
||||
"markdown": {
|
||||
"content": "<font color=\"warning\">233</font>"
|
||||
}
|
||||
}`
|
||||
var markdownMsg markdownMessage
|
||||
err := json.Unmarshal([]byte(jsonString), &markdownMsg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, markdownMsg.MsgType, "markdown")
|
||||
assert.Equal(t, markdownMsg.Markdown.Content,
|
||||
"<font color=\"warning\">233</font>")
|
||||
}
|
5
message.go
Normal file
5
message.go
Normal file
@ -0,0 +1,5 @@
|
||||
package wxworkbot
|
||||
|
||||
type message struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
}
|
17
news.go
Normal file
17
news.go
Normal file
@ -0,0 +1,17 @@
|
||||
package wxworkbot
|
||||
|
||||
type newsMessage struct {
|
||||
message
|
||||
News News `json:"news"`
|
||||
}
|
||||
|
||||
type News struct {
|
||||
Articles []NewsArticle `json:"articles"`
|
||||
}
|
||||
|
||||
type NewsArticle struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
PicURL string `json:"picurl"`
|
||||
}
|
35
news_test.go
Normal file
35
news_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewsMessage(t *testing.T) {
|
||||
jsonString := `
|
||||
{
|
||||
"msgtype": "news",
|
||||
"news": {
|
||||
"articles" : [
|
||||
{
|
||||
"title" : "中秋节礼品领取",
|
||||
"description" : "今年中秋节公司有豪礼相送",
|
||||
"url" : "URL",
|
||||
"picurl" : "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
var newsMsg newsMessage
|
||||
err := json.Unmarshal([]byte(jsonString), &newsMsg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, newsMsg.MsgType, "news")
|
||||
assert.NotEmpty(t, newsMsg.News.Articles)
|
||||
article := newsMsg.News.Articles[0]
|
||||
assert.Equal(t, article.Title, "中秋节礼品领取")
|
||||
assert.Equal(t, article.Description, "今年中秋节公司有豪礼相送")
|
||||
assert.Equal(t, article.URL, "URL")
|
||||
assert.Equal(t, article.PicURL, "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png")
|
||||
}
|
12
text.go
Normal file
12
text.go
Normal file
@ -0,0 +1,12 @@
|
||||
package wxworkbot
|
||||
|
||||
type textMessage struct {
|
||||
message
|
||||
Text Text `json:"text"`
|
||||
}
|
||||
|
||||
type Text struct {
|
||||
Content string `json:"content"`
|
||||
MentionedList []string `json:"mentioned_list"`
|
||||
MentionedMobileList []string `json:"mentioned_mobile_list"`
|
||||
}
|
26
text_test.go
Normal file
26
text_test.go
Normal file
@ -0,0 +1,26 @@
|
||||
package wxworkbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTextMessage(t *testing.T) {
|
||||
jsonString := `
|
||||
{
|
||||
"msgtype": "text",
|
||||
"text": {
|
||||
"content": "广州今日天气:29度,大部分多云,降雨概率:60%",
|
||||
"mentioned_list":["wangqing","@all"],
|
||||
"mentioned_mobile_list":["13800001111","@all"]
|
||||
}
|
||||
}`
|
||||
var textMsg textMessage
|
||||
err := json.Unmarshal([]byte(jsonString), &textMsg)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, textMsg.MsgType, "text")
|
||||
assert.Equal(t, textMsg.Text.Content, "广州今日天气:29度,大部分多云,降雨概率:60%")
|
||||
assert.Equal(t, textMsg.Text.MentionedList, []string{"wangqing", "@all"})
|
||||
assert.Equal(t, textMsg.Text.MentionedMobileList, []string{"13800001111", "@all"})
|
||||
}
|
Loading…
Reference in New Issue
Block a user