增加vendor
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
企业微信会话存档SDK(基于企业微信C版官方SDK封装),暂时只支持在`linux`环境下使用当前SDK。
|
||||
|
||||
|
||||
### 官方文档地址
|
||||
https://open.work.weixin.qq.com/api/doc/90000/90135/91774
|
||||
|
||||
### 使用方式
|
||||
|
||||
1、安装 go module
|
||||
> go get -u github.com/silenceper/wechat/v2
|
||||
|
||||
2、从 `github.com/silenceper/wechat/v2/work/msgaudit/lib` 文件夹下复制 `libWeWorkFinanceSdk_C.so` 动态库文件到系统动态链接库默认文件夹下,或者复制到任意文件夹并在当前文件夹下执行 `export LD_LIBRARY_PATH=$(pwd)`命令设置动态链接库检索地址后即可正常使用
|
||||
|
||||
3、编译要求
|
||||
- 开启CGO: `CGO_ENABLED=1`
|
||||
- 增加tags参数`msgaudit`: `go build -tags msgaudit`或者`go run -tags msgaudit main.go`
|
||||
|
||||
### Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2"
|
||||
"github.com/silenceper/wechat/v2/work/msgaudit"
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//初始化客户端
|
||||
wechatClient := wechat.NewWechat()
|
||||
|
||||
workClient := wechatClient.GetWork(&config.Config{
|
||||
CorpID: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
CorpSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
RasPrivateKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
})
|
||||
|
||||
client, err := workClient.GetMsgAudit()
|
||||
if err != nil {
|
||||
fmt.Printf("SDK 初始化失败:%v \n", err)
|
||||
return
|
||||
}
|
||||
|
||||
//同步消息
|
||||
chatDataList, err := client.GetChatData(0, 100, "", "", 3)
|
||||
if err != nil {
|
||||
fmt.Printf("消息同步失败:%v \n", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, chatData := range chatDataList {
|
||||
//消息解密
|
||||
chatInfo, err := client.DecryptData(chatData.EncryptRandomKey, chatData.EncryptChatMsg)
|
||||
if err != nil {
|
||||
fmt.Printf("消息解密失败:%v \n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if chatInfo.Type == "image" {
|
||||
image, _ := chatInfo.GetImageMessage()
|
||||
sdkFileID := image.Image.SdkFileID
|
||||
|
||||
isFinish := false
|
||||
buffer := bytes.Buffer{}
|
||||
indexBuf := ""
|
||||
for !isFinish {
|
||||
//获取媒体数据
|
||||
mediaData, err := client.GetMediaData(indexBuf, sdkFileID, "", "", 5)
|
||||
if err != nil {
|
||||
fmt.Printf("媒体数据拉取失败:%v \n", err)
|
||||
return
|
||||
}
|
||||
buffer.Write(mediaData.Data)
|
||||
if mediaData.IsFinish {
|
||||
isFinish = mediaData.IsFinish
|
||||
}
|
||||
indexBuf = mediaData.OutIndexBuf
|
||||
}
|
||||
filePath, _ := os.Getwd()
|
||||
filePath = path.Join(filePath, "test.png")
|
||||
err := ioutil.WriteFile(filePath, buffer.Bytes(), 0666)
|
||||
if err != nil {
|
||||
fmt.Printf("文件存储失败:%v \n", err)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//释放SDK实例
|
||||
client.Free()
|
||||
}
|
||||
|
||||
|
||||
|
||||
```
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
package msgaudit
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// ChatDataResponse 会话存档消息响应数据
|
||||
type ChatDataResponse struct {
|
||||
Error
|
||||
ChatDataList []ChatData `json:"chatdata,omitempty"`
|
||||
}
|
||||
|
||||
// IsError 判断是否正确响应
|
||||
func (c ChatDataResponse) IsError() bool {
|
||||
return c.ErrCode != 0
|
||||
}
|
||||
|
||||
// ChatData 会话存档原始数据
|
||||
type ChatData struct {
|
||||
Seq uint64 `json:"seq,omitempty"` // 消息的seq值,标识消息的序号。再次拉取需要带上上次回包中最大的seq。Uint64类型,范围0-pow(2,64)-1
|
||||
MsgID string `json:"msgid,omitempty"` // 消息id,消息的唯一标识,企业可以使用此字段进行消息去重。
|
||||
PublickeyVer uint32 `json:"publickey_ver,omitempty"` // 加密此条消息使用的公钥版本号。
|
||||
EncryptRandomKey string `json:"encrypt_random_key,omitempty"` // 使用publickey_ver指定版本的公钥进行非对称加密后base64加密的内容,需要业务方先base64 decode处理后,再使用指定版本的私钥进行解密,得出内容。
|
||||
EncryptChatMsg string `json:"encrypt_chat_msg,omitempty"` // 消息密文。需要业务方使用将encrypt_random_key解密得到的内容,与encrypt_chat_msg,传入sdk接口DecryptData,得到消息明文。
|
||||
}
|
||||
|
||||
// ChatMessage 会话存档消息
|
||||
type ChatMessage struct {
|
||||
ID string // 消息id,消息的唯一标识,企业可以使用此字段进行消息去重。
|
||||
From string // 消息发送方id。同一企业内容为userid,非相同企业为external_userid。消息如果是机器人发出,也为external_userid。
|
||||
ToList []string // 消息接收方列表,可能是多个,同一个企业内容为userid,非相同企业为external_userid。
|
||||
Action string // 消息动作,目前有send(发送消息)/recall(撤回消息)/switch(切换企业日志)三种类型。
|
||||
Type string // 消息类型
|
||||
originData []byte // 原始消息对象
|
||||
}
|
||||
|
||||
// GetOriginMessage 获取消息原始数据
|
||||
func (c ChatMessage) GetOriginMessage() (msg map[string]interface{}, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetTextMessage 获取文本消息
|
||||
func (c ChatMessage) GetTextMessage() (msg TextMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetImageMessage 获取图片消息
|
||||
func (c ChatMessage) GetImageMessage() (msg ImageMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetRevokeMessage 获取撤回消息
|
||||
func (c ChatMessage) GetRevokeMessage() (msg RevokeMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetAgreeMessage 获取同意会话聊天内容
|
||||
func (c ChatMessage) GetAgreeMessage() (msg AgreeMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetVoiceMessage 获取语音消息
|
||||
func (c ChatMessage) GetVoiceMessage() (msg VoiceMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetVideoMessage 获取视频消息
|
||||
func (c ChatMessage) GetVideoMessage() (msg VideoMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetCardMessage 获取名片消息
|
||||
func (c ChatMessage) GetCardMessage() (msg CardMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetLocationMessage 获取位置消息
|
||||
func (c ChatMessage) GetLocationMessage() (msg LocationMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetEmotionMessage 获取表情消息
|
||||
func (c ChatMessage) GetEmotionMessage() (msg EmotionMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetFileMessage 获取文件消息
|
||||
func (c ChatMessage) GetFileMessage() (msg FileMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetLinkMessage 获取链接消息
|
||||
func (c ChatMessage) GetLinkMessage() (msg LinkMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetWeappMessage 获取小程序消息
|
||||
func (c ChatMessage) GetWeappMessage() (msg WeappMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetChatRecordMessage 获取会话记录消息
|
||||
func (c ChatMessage) GetChatRecordMessage() (msg ChatRecordMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetTodoMessage 获取待办消息
|
||||
func (c ChatMessage) GetTodoMessage() (msg TodoMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetVoteMessage 获取投票消息
|
||||
func (c ChatMessage) GetVoteMessage() (msg VoteMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetCollectMessage 获取填表消息
|
||||
func (c ChatMessage) GetCollectMessage() (msg CollectMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetRedpacketMessage 获取红包消息
|
||||
func (c ChatMessage) GetRedpacketMessage() (msg RedpacketMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetMeetingMessage 获取会议邀请消息
|
||||
func (c ChatMessage) GetMeetingMessage() (msg MeetingMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetDocMessage 获取在线文档消息
|
||||
func (c ChatMessage) GetDocMessage() (msg DocMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetMarkdownMessage 获取MarkDown格式消息
|
||||
func (c ChatMessage) GetMarkdownMessage() (msg MarkdownMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetNewsMessage 获取图文消息
|
||||
func (c ChatMessage) GetNewsMessage() (msg NewsMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetCalendarMessage 获取日程消息
|
||||
func (c ChatMessage) GetCalendarMessage() (msg CalendarMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetMixedMessage 获取混合消息
|
||||
func (c ChatMessage) GetMixedMessage() (msg MixedMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetMeetingVoiceCallMessage 获取音频存档消息
|
||||
func (c ChatMessage) GetMeetingVoiceCallMessage() (msg MeetingVoiceCallMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetVoipDocShareMessage 获取音频共享消息
|
||||
func (c ChatMessage) GetVoipDocShareMessage() (msg VoipDocShareMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetExternalRedPacketMessage 获取互通红包消息
|
||||
func (c ChatMessage) GetExternalRedPacketMessage() (msg ExternalRedPacketMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetSphFeedMessage 获取视频号消息
|
||||
func (c ChatMessage) GetSphFeedMessage() (msg SphFeedMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetSwitchMessage 获取切换企业日志
|
||||
func (c ChatMessage) GetSwitchMessage() (msg SwitchMessage, err error) {
|
||||
err = json.Unmarshal(c.originData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
//go:build linux && cgo && msgaudit
|
||||
// +build linux,cgo,msgaudit
|
||||
|
||||
// Package msgaudit only for linux
|
||||
package msgaudit
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/lib -lWeWorkFinanceSdk_C
|
||||
// #cgo CFLAGS: -I ./lib/
|
||||
// #include <stdlib.h>
|
||||
// #include "WeWorkFinanceSdk_C.h"
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"unsafe"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
)
|
||||
|
||||
// Client 会话存档
|
||||
type Client struct {
|
||||
ptr *C.WeWorkFinanceSdk_t
|
||||
privateKey string
|
||||
}
|
||||
|
||||
// NewClient 初始会话会话存档实例
|
||||
/**
|
||||
* 初始化函数
|
||||
* Return值=0表示该API调用成功
|
||||
*
|
||||
* @param [in] sdk NewSdk返回的sdk指针
|
||||
* @param [in] corpid 调用企业的企业id,例如:wwd08c8exxxx5ab44d,可以在企业微信管理端--我的企业--企业信息查看
|
||||
* @param [in] secret 聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
|
||||
* @param [in] privateKey 消息加密私钥,可以在企业微信管理端--管理工具--消息加密公钥查看对用公钥,私钥一般由自己保存
|
||||
*
|
||||
*
|
||||
* @return 返回是否初始化成功
|
||||
* 0 - 成功
|
||||
* !=0 - 失败
|
||||
*/
|
||||
func NewClient(cfg *config.Config) (*Client, error) {
|
||||
ptr := C.NewSdk()
|
||||
corpIDC := C.CString(cfg.CorpID)
|
||||
corpSecretC := C.CString(cfg.CorpSecret)
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(corpIDC))
|
||||
C.free(unsafe.Pointer(corpSecretC))
|
||||
}()
|
||||
retC := C.Init(ptr, corpIDC, corpSecretC)
|
||||
ret := int(retC)
|
||||
if ret != 0 {
|
||||
return nil, NewSDKErr(ret)
|
||||
}
|
||||
return &Client{
|
||||
ptr: ptr,
|
||||
privateKey: cfg.RasPrivateKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Free 释放SDK实例是可调用该方法释放内存
|
||||
func (s *Client) Free() {
|
||||
if s.ptr == nil {
|
||||
return
|
||||
}
|
||||
C.DestroySdk(s.ptr)
|
||||
s.ptr = nil
|
||||
}
|
||||
|
||||
// GetChatData 拉取聊天记录函数
|
||||
/**
|
||||
* 拉取聊天记录函数
|
||||
*
|
||||
*
|
||||
* @param [in] seq 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0
|
||||
* @param [in] limit 一次拉取的消息条数,最大值1000条,超过1000条会返回错误
|
||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||
* @param [in] timeout 超时时间,单位秒
|
||||
* @return chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。示例如下:
|
||||
|
||||
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
||||
*/
|
||||
func (s *Client) GetChatData(seq uint64, limit uint64, proxy string, passwd string, timeout int) ([]ChatData, error) {
|
||||
proxyC := C.CString(proxy)
|
||||
passwdC := C.CString(passwd)
|
||||
chatSlice := C.NewSlice()
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(proxyC))
|
||||
C.free(unsafe.Pointer(passwdC))
|
||||
C.FreeSlice(chatSlice)
|
||||
}()
|
||||
|
||||
if s.ptr == nil {
|
||||
return nil, NewSDKErr(10002)
|
||||
}
|
||||
|
||||
retC := C.GetChatData(s.ptr, C.ulonglong(seq), C.uint(limit), proxyC, passwdC, C.int(timeout), chatSlice)
|
||||
ret := int(retC)
|
||||
if ret != 0 {
|
||||
return nil, NewSDKErr(ret)
|
||||
}
|
||||
buf := s.GetContentFromSlice(chatSlice)
|
||||
|
||||
var data ChatDataResponse
|
||||
err := json.Unmarshal(buf, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data.ErrCode != 0 {
|
||||
return nil, data.Error
|
||||
}
|
||||
return data.ChatDataList, nil
|
||||
}
|
||||
|
||||
// GetRawChatData 拉取聊天记录函数
|
||||
/**
|
||||
* 拉取聊天记录函数
|
||||
*
|
||||
*
|
||||
* @param [in] seq 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0
|
||||
* @param [in] limit 一次拉取的消息条数,最大值1000条,超过1000条会返回错误
|
||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||
* @param [in] timeout 超时时间,单位秒
|
||||
* @return chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。示例如下:
|
||||
|
||||
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
||||
*/
|
||||
func (s *Client) GetRawChatData(seq uint64, limit uint64, proxy string, passwd string, timeout int) (ChatDataResponse, error) {
|
||||
proxyC := C.CString(proxy)
|
||||
passwdC := C.CString(passwd)
|
||||
chatSlice := C.NewSlice()
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(proxyC))
|
||||
C.free(unsafe.Pointer(passwdC))
|
||||
C.FreeSlice(chatSlice)
|
||||
}()
|
||||
|
||||
if s.ptr == nil {
|
||||
return ChatDataResponse{}, NewSDKErr(10002)
|
||||
}
|
||||
|
||||
retC := C.GetChatData(s.ptr, C.ulonglong(seq), C.uint(limit), proxyC, passwdC, C.int(timeout), chatSlice)
|
||||
ret := int(retC)
|
||||
if ret != 0 {
|
||||
return ChatDataResponse{}, NewSDKErr(ret)
|
||||
}
|
||||
buf := s.GetContentFromSlice(chatSlice)
|
||||
|
||||
var data ChatDataResponse
|
||||
err := json.Unmarshal(buf, &data)
|
||||
if err != nil {
|
||||
return ChatDataResponse{}, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// DecryptData 解析密文.企业微信自有解密内容
|
||||
/**
|
||||
* @brief 解析密文.企业微信自有解密内容
|
||||
* @param [in] encrypt_key, getchatdata返回的encrypt_random_key,使用企业自持对应版本秘钥RSA解密后的内容
|
||||
* @param [in] encrypt_msg, getchatdata返回的encrypt_chat_msg
|
||||
* @param [out] msg, 解密的消息明文
|
||||
* @return 返回是否调用成功
|
||||
* 0 - 成功
|
||||
* !=0 - 失败
|
||||
*/
|
||||
func (s *Client) DecryptData(encryptRandomKey string, encryptMsg string) (msg ChatMessage, err error) {
|
||||
encryptKey, err := util.RSADecryptBase64(s.privateKey, encryptRandomKey)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
encryptKeyC := C.CString(string(encryptKey))
|
||||
encryptMsgC := C.CString(encryptMsg)
|
||||
msgSlice := C.NewSlice()
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(encryptKeyC))
|
||||
C.free(unsafe.Pointer(encryptMsgC))
|
||||
C.FreeSlice(msgSlice)
|
||||
}()
|
||||
|
||||
retC := C.DecryptData(encryptKeyC, encryptMsgC, msgSlice)
|
||||
ret := int(retC)
|
||||
if ret != 0 {
|
||||
return msg, NewSDKErr(ret)
|
||||
}
|
||||
buf := s.GetContentFromSlice(msgSlice)
|
||||
|
||||
// handle illegal escape character in text
|
||||
for i := 0; i < len(buf); {
|
||||
if buf[i] < 0x20 {
|
||||
buf = append(buf[:i], buf[i+1:]...)
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
var baseMessage BaseMessage
|
||||
err = json.Unmarshal(buf, &baseMessage)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
|
||||
msg.ID = baseMessage.MsgID
|
||||
msg.From = baseMessage.From
|
||||
msg.ToList = baseMessage.ToList
|
||||
msg.Action = baseMessage.Action
|
||||
msg.Type = baseMessage.MsgType
|
||||
msg.originData = buf
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// GetMediaData 拉取媒体消息函数
|
||||
/**
|
||||
* 拉取媒体消息函数
|
||||
* Return值=0表示该API调用成功
|
||||
*
|
||||
*
|
||||
* @param [in] sdk NewSdk返回的sdk指针
|
||||
* @param [in] sdkFileid 从GetChatData返回的聊天消息中,媒体消息包括的sdkfileid
|
||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||
* @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取512k,后续每次调用只需要将上次调用返回的outindexbuf填入即可。
|
||||
* @param [in] timeout 超时时间,单位秒
|
||||
* @param [out] media_data 返回本次拉取的媒体数据.MediaData结构体.内容包括data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记)
|
||||
|
||||
*
|
||||
* @return 返回是否调用成功
|
||||
* 0 - 成功
|
||||
* !=0 - 失败
|
||||
*/
|
||||
func (s *Client) GetMediaData(indexBuf string, sdkFileID string, proxy string, passwd string, timeout int) (*MediaData, error) {
|
||||
indexBufC := C.CString(indexBuf)
|
||||
sdkFileIDC := C.CString(sdkFileID)
|
||||
proxyC := C.CString(proxy)
|
||||
passwdC := C.CString(passwd)
|
||||
mediaDataC := C.NewMediaData()
|
||||
defer func() {
|
||||
C.free(unsafe.Pointer(indexBufC))
|
||||
C.free(unsafe.Pointer(sdkFileIDC))
|
||||
C.free(unsafe.Pointer(proxyC))
|
||||
C.free(unsafe.Pointer(passwdC))
|
||||
C.FreeMediaData(mediaDataC)
|
||||
}()
|
||||
|
||||
if s.ptr == nil {
|
||||
return nil, NewSDKErr(10002)
|
||||
}
|
||||
|
||||
retC := C.GetMediaData(s.ptr, indexBufC, sdkFileIDC, proxyC, passwdC, C.int(timeout), mediaDataC)
|
||||
ret := int(retC)
|
||||
if ret != 0 {
|
||||
return nil, NewSDKErr(ret)
|
||||
}
|
||||
return &MediaData{
|
||||
OutIndexBuf: C.GoString(C.GetOutIndexBuf(mediaDataC)),
|
||||
Data: C.GoBytes(unsafe.Pointer(C.GetData(mediaDataC)), C.GetDataLen(mediaDataC)),
|
||||
IsFinish: int(C.IsMediaDataFinish(mediaDataC)) == 1,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetContentFromSlice 从切片内获取内容
|
||||
func (s *Client) GetContentFromSlice(slice *C.struct_Slice_t) []byte {
|
||||
return C.GoBytes(unsafe.Pointer(C.GetContentFromSlice(slice)), C.GetSliceLen(slice))
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
//go:build !linux || !cgo || !msgaudit
|
||||
// +build !linux !cgo !msgaudit
|
||||
|
||||
// Package msgaudit for unsupport platform
|
||||
package msgaudit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
)
|
||||
|
||||
// Client 会话存档
|
||||
type Client struct {
|
||||
}
|
||||
|
||||
// NewClient new
|
||||
func NewClient(cfg *config.Config) (*Client, error) {
|
||||
return nil, fmt.Errorf("会话存档功能目前只支持Linux平台运行,并且打开设置CGO_ENABLED=1")
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package msgaudit
|
||||
|
||||
// Config 会话存档初始化参数
|
||||
type Config struct {
|
||||
CorpID string // 调用企业的企业id,例如:wwd08c8exxxx5ab44d,可以在企业微信管理端--我的企业--企业信息查看
|
||||
CorpSecret string // 聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
|
||||
RasPrivateKey string // 消息加密私钥,可以在企业微信管理端--管理工具--消息加密公钥查看对用公钥,私钥一般由自己保存
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package msgaudit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//返回码 错误说明
|
||||
//10000 参数错误,请求参数错误
|
||||
//10001 网络错误,网络请求错误
|
||||
//10002 数据解析失败
|
||||
//10003 系统失败
|
||||
//10004 密钥错误导致加密失败
|
||||
//10005 fileid错误
|
||||
//10006 解密失败
|
||||
//10007 找不到消息加密版本的私钥,需要重新传入私钥对
|
||||
//10008 解析encrypt_key出错
|
||||
//10009 ip非法
|
||||
//10010 数据过期
|
||||
//10011 证书错误
|
||||
const (
|
||||
SDKErrMsg = "sdk failed"
|
||||
SDKParamsErrMsg = "参数错误,请求参数错误"
|
||||
SDKNetworkErrMsg = "网络错误,网络请求错误"
|
||||
SDKParseErrMsg = "数据解析失败"
|
||||
SDKSystemErrMsg = "系统失败"
|
||||
SDKSecretErrMsg = "密钥错误导致加密失败"
|
||||
SDKFileIDErrMsg = "fileid错误"
|
||||
SDKDecryptErrMsg = "解密失败"
|
||||
SDKSecretMissErrMsg = "找不到消息加密版本的私钥,需要重新传入私钥对"
|
||||
SDKEncryptKeyErrMsg = "解析encrypt_key出错"
|
||||
SDKIPNotWhiteListErrMsg = "ip非法"
|
||||
SDKDataExpiredErrMsg = "数据过期"
|
||||
SDKTokenExpiredErrMsg = "证书过期"
|
||||
)
|
||||
|
||||
// Error 错误
|
||||
type Error struct {
|
||||
ErrCode int `json:"errcode,omitempty"`
|
||||
ErrMsg string `json:"errmsg,omitempty"`
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return fmt.Sprintf("%d:%s", e.ErrCode, e.ErrMsg)
|
||||
}
|
||||
|
||||
// NewSDKErr 初始化新的SDK错误
|
||||
func NewSDKErr(code int) Error {
|
||||
msg := ""
|
||||
switch code {
|
||||
case 10000:
|
||||
msg = SDKParamsErrMsg
|
||||
case 10001:
|
||||
msg = SDKNetworkErrMsg
|
||||
case 10002:
|
||||
msg = SDKParseErrMsg
|
||||
case 10003:
|
||||
msg = SDKSystemErrMsg
|
||||
case 10004:
|
||||
msg = SDKSecretErrMsg
|
||||
case 10005:
|
||||
msg = SDKFileIDErrMsg
|
||||
case 10006:
|
||||
msg = SDKDecryptErrMsg
|
||||
case 10007:
|
||||
msg = SDKSecretMissErrMsg
|
||||
case 10008:
|
||||
msg = SDKEncryptKeyErrMsg
|
||||
case 10009:
|
||||
msg = SDKIPNotWhiteListErrMsg
|
||||
case 10010:
|
||||
msg = SDKDataExpiredErrMsg
|
||||
case 10011:
|
||||
msg = SDKTokenExpiredErrMsg
|
||||
}
|
||||
return Error{ErrCode: code, ErrMsg: msg}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package msgaudit
|
||||
|
||||
// MediaData 媒体文件数据
|
||||
type MediaData struct {
|
||||
OutIndexBuf string `json:"outindexbuf,omitempty"`
|
||||
IsFinish bool `json:"is_finish,omitempty"`
|
||||
Data []byte `json:"data,omitempty"`
|
||||
}
|
||||
+352
@@ -0,0 +1,352 @@
|
||||
package msgaudit
|
||||
|
||||
// BaseMessage 基础消息
|
||||
type BaseMessage struct {
|
||||
MsgID string `json:"msgid,omitempty"` // 消息id,消息的唯一标识,企业可以使用此字段进行消息去重。
|
||||
Action string `json:"action,omitempty"` // 消息动作,目前有send(发送消息)/recall(撤回消息)/switch(切换企业日志)三种类型。
|
||||
From string `json:"from,omitempty"` // 消息发送方id。同一企业内容为userid,非相同企业为external_userid。消息如果是机器人发出,也为external_userid。
|
||||
ToList []string `json:"tolist,omitempty"` // 消息接收方列表,可能是多个,同一个企业内容为userid,非相同企业为external_userid。
|
||||
RoomID string `json:"roomid,omitempty"` // 群聊消息的群id。如果是单聊则为空。
|
||||
MsgTime int64 `json:"msgtime,omitempty"` // 消息发送时间戳,utc时间,ms单位。
|
||||
MsgType string `json:"msgtype,omitempty"` // 文本消息为:text。
|
||||
}
|
||||
|
||||
// TextMessage 文本消息
|
||||
type TextMessage struct {
|
||||
BaseMessage
|
||||
Text struct {
|
||||
Content string `json:"content,omitempty"` // 消息内容。
|
||||
} `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
// ImageMessage 图片消息
|
||||
type ImageMessage struct {
|
||||
BaseMessage
|
||||
Image struct {
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 媒体资源的id信息。
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 图片资源的md5值,供进行校验。
|
||||
FileSize uint32 `json:"filesize,omitempty"` // 图片资源的文件大小。
|
||||
} `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
// RevokeMessage 撤回消息
|
||||
type RevokeMessage struct {
|
||||
BaseMessage
|
||||
Revoke struct {
|
||||
PreMsgID string `json:"pre_msgid,omitempty"` // 标识撤回的原消息的msgid
|
||||
} `json:"revoke,omitempty"`
|
||||
}
|
||||
|
||||
// AgreeMessage 同意会话聊天内容
|
||||
type AgreeMessage struct {
|
||||
BaseMessage
|
||||
Agree struct {
|
||||
UserID string `json:"userid,omitempty"` // 同意/不同意协议者的userid,外部企业默认为external_userid。
|
||||
AgreeTime int64 `json:"agree_time,omitempty"` // 同意/不同意协议的时间,utc时间,ms单位。
|
||||
} `json:"agree,omitempty"`
|
||||
}
|
||||
|
||||
// VoiceMessage 语音消息
|
||||
type VoiceMessage struct {
|
||||
BaseMessage
|
||||
Voice struct {
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 媒体资源的id信息。
|
||||
VoiceSize uint32 `json:"voice_size,omitempty"` // 语音消息大小。
|
||||
PlayLength uint32 `json:"play_length,omitempty"` // 播放长度。
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 图片资源的md5值,供进行校验。
|
||||
} `json:"voice,omitempty"`
|
||||
}
|
||||
|
||||
// VideoMessage 视频消息
|
||||
type VideoMessage struct {
|
||||
BaseMessage
|
||||
Video struct {
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 媒体资源的id信息。
|
||||
FileSize uint32 `json:"filesize,omitempty"` // 图片资源的文件大小。
|
||||
PlayLength uint32 `json:"play_length,omitempty"` // 播放长度。
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 图片资源的md5值,供进行校验。
|
||||
} `json:"video,omitempty"`
|
||||
}
|
||||
|
||||
// CardMessage 名片消息
|
||||
type CardMessage struct {
|
||||
BaseMessage
|
||||
Card struct {
|
||||
CorpName string `json:"corpname,omitempty"` // 名片所有者所在的公司名称。
|
||||
UserID string `json:"userid,omitempty"` // 名片所有者的id,同一公司是userid,不同公司是external_userid
|
||||
} `json:"card,omitempty"`
|
||||
}
|
||||
|
||||
// LocationMessage 位置消息
|
||||
type LocationMessage struct {
|
||||
BaseMessage
|
||||
Location struct {
|
||||
Lng float64 `json:"longitude,omitempty"` // 经度,单位double
|
||||
Lat float64 `json:"latitude,omitempty"` // 纬度,单位double
|
||||
Address string `json:"address,omitempty"` // 地址信息
|
||||
Title string `json:"title,omitempty"` // 位置信息的title。
|
||||
Zoom uint32 `json:"zoom,omitempty"` // 缩放比例。
|
||||
} `json:"location,omitempty"`
|
||||
}
|
||||
|
||||
// EmotionMessage 表情消息
|
||||
type EmotionMessage struct {
|
||||
BaseMessage
|
||||
Emotion struct {
|
||||
Type uint32 `json:"type,omitempty"` // 表情类型,png或者gif.1表示gif 2表示png。
|
||||
Width uint32 `json:"width,omitempty"` // 表情图片宽度。
|
||||
Height uint32 `json:"height,omitempty"` // 表情图片高度。
|
||||
ImageSize uint32 `json:"imagesize,omitempty"` // 资源的文件大小。
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 媒体资源的id信息。
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 图片资源的md5值,供进行校验。
|
||||
} `json:"emotion,omitempty"`
|
||||
}
|
||||
|
||||
// FileMessage 文件消息
|
||||
type FileMessage struct {
|
||||
BaseMessage
|
||||
File struct {
|
||||
FileName string `json:"filename,omitempty"` // 文件名称。
|
||||
FileExt string `json:"fileext,omitempty"` // 文件类型后缀。
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 媒体资源的id信息。
|
||||
FileSize uint32 `json:"filesize,omitempty"` // 文件大小。
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 资源的md5值,供进行校验。
|
||||
} `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// LinkMessage 链接消息
|
||||
type LinkMessage struct {
|
||||
BaseMessage
|
||||
Link struct {
|
||||
Title string `json:"title,omitempty"` // 消息标题。
|
||||
Desc string `json:"description,omitempty"` // 消息描述。
|
||||
LinkURL string `json:"link_url,omitempty"` // 链接url地址
|
||||
ImageURL string `json:"image_url,omitempty"` // 链接图片url。
|
||||
} `json:"link,omitempty"`
|
||||
}
|
||||
|
||||
// WeappMessage 小程序消息
|
||||
type WeappMessage struct {
|
||||
BaseMessage
|
||||
WeApp struct {
|
||||
Title string `json:"title,omitempty"` // 消息标题。
|
||||
Desc string `json:"description,omitempty"` // 消息描述。
|
||||
Username string `json:"username,omitempty"` // 用户名称。
|
||||
DisplayName string `json:"displayname,omitempty"` // 小程序名称
|
||||
} `json:"weapp,omitempty"`
|
||||
}
|
||||
|
||||
// ChatRecordMessage 会话记录消息
|
||||
type ChatRecordMessage struct {
|
||||
BaseMessage
|
||||
ChatRecord struct {
|
||||
Title string `json:"title,omitempty"` // 聊天记录标题
|
||||
Item []ChatRecord `json:"item,omitempty"` // 消息记录内的消息内容,批量数据
|
||||
} `json:"chatrecord,omitempty"`
|
||||
}
|
||||
|
||||
// TodoMessage 待办消息
|
||||
type TodoMessage struct {
|
||||
BaseMessage
|
||||
Todo struct {
|
||||
Title string `json:"title,omitempty"` // 代办的来源文本
|
||||
Content string `json:"content,omitempty"` // 代办的具体内容
|
||||
} `json:"todo,omitempty"`
|
||||
}
|
||||
|
||||
// VoteMessage 投票消息
|
||||
type VoteMessage struct {
|
||||
BaseMessage
|
||||
VoteTitle string `json:"votetitle,omitempty"` // 投票主题。
|
||||
VoteItem []string `json:"voteitem,omitempty"` // 投票选项,可能多个内容。
|
||||
VoteType uint32 `json:"votetype,omitempty"` // 投票类型.101发起投票、102参与投票。
|
||||
VoteID string `json:"voteid,omitempty"` // 投票id,方便将参与投票消息与发起投票消息进行前后对照。
|
||||
}
|
||||
|
||||
// CollectMessage 填表消息
|
||||
type CollectMessage struct {
|
||||
BaseMessage
|
||||
Collect struct {
|
||||
RoomName string `json:"room_name,omitempty"` // 填表消息所在的群名称。
|
||||
Creator string `json:"creator,omitempty"` // 创建者在群中的名字
|
||||
CreateTime string `json:"create_time,omitempty"` // 创建的时间
|
||||
Details []CollectDetails `json:"details,omitempty"` // 表内容
|
||||
} `json:"collect,omitempty"`
|
||||
}
|
||||
|
||||
// RedpacketMessage 红包消息
|
||||
type RedpacketMessage struct {
|
||||
BaseMessage
|
||||
RedPacket struct {
|
||||
Type uint32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包、3 激励群红包。
|
||||
Wish string `json:"wish,omitempty"` // 红包祝福语
|
||||
TotalCnt uint32 `json:"totalcnt,omitempty"` // 红包总个数
|
||||
TotalAmount uint32 `json:"totalamount,omitempty"` // 红包总金额。单位为分。
|
||||
} `json:"redpacket,omitempty"`
|
||||
}
|
||||
|
||||
// MeetingMessage 会议邀请消息
|
||||
type MeetingMessage struct {
|
||||
BaseMessage
|
||||
Meeting struct {
|
||||
Topic string `json:"topic,omitempty"` // 会议主题
|
||||
StartTime int64 `json:"starttime,omitempty"` // 会议开始时间。Utc时间
|
||||
EndTime int64 `json:"endtime,omitempty"` // 会议结束时间。Utc时间
|
||||
Address string `json:"address,omitempty"` // 会议地址
|
||||
Remarks string `json:"remarks,omitempty"` // 会议备注
|
||||
MeetingType uint32 `json:"meetingtype,omitempty"` // 会议消息类型。101发起会议邀请消息、102处理会议邀请消息
|
||||
MeetingID uint64 `json:"meetingid,omitempty"` // 会议id。方便将发起、处理消息进行对照
|
||||
Status uint32 `json:"status,omitempty"` // 会议邀请处理状态。1 参加会议、2 拒绝会议、3 待定、4 未被邀请、5 会议已取消、6 会议已过期、7 不在房间内。
|
||||
} `json:"meeting,omitempty"`
|
||||
}
|
||||
|
||||
// DocMessage 在线文档消息
|
||||
type DocMessage struct {
|
||||
BaseMessage
|
||||
Doc struct {
|
||||
Title string `json:"title,omitempty"` // 在线文档名称
|
||||
LinkURL string `json:"link_url,omitempty"` // 在线文档链接
|
||||
DocCreator string `json:"doc_creator,omitempty"` // 在线文档创建者。本企业成员创建为userid;外部企业成员创建为external_userid
|
||||
} `json:"doc,omitempty"`
|
||||
}
|
||||
|
||||
// MarkdownMessage MarkDown消息
|
||||
type MarkdownMessage struct {
|
||||
BaseMessage
|
||||
Info struct {
|
||||
Content string `json:"content,omitempty"` // markdown消息内容,目前为机器人发出的消息
|
||||
} `json:"info,omitempty"`
|
||||
}
|
||||
|
||||
// NewsMessage 图文消息
|
||||
type NewsMessage struct {
|
||||
BaseMessage
|
||||
Info struct {
|
||||
Item []News `json:"item,omitempty"` // 图文消息数组
|
||||
} `json:"info,omitempty"` // 图文消息的内容
|
||||
}
|
||||
|
||||
// CalendarMessage 日程消息
|
||||
type CalendarMessage struct {
|
||||
BaseMessage
|
||||
Calendar struct {
|
||||
Title string `json:"title,omitempty"` // 日程主题
|
||||
CreatorName string `json:"creatorname,omitempty"` // 日程组织者
|
||||
AttendeeName []string `json:"attendeename,omitempty"` // 日程参与人。数组,内容为String类型
|
||||
StartTime int64 `json:"starttime,omitempty"` // 日程开始时间。Utc时间,单位秒
|
||||
EndTime int64 `json:"endtime,omitempty"` // 日程结束时间。Utc时间,单位秒
|
||||
Place string `json:"place,omitempty"` // 日程地点
|
||||
Remarks string `json:"remarks,omitempty"` // 日程备注
|
||||
} `json:"calendar,omitempty"`
|
||||
}
|
||||
|
||||
// MixedMessage 混合消息
|
||||
type MixedMessage struct {
|
||||
BaseMessage
|
||||
Mixed struct {
|
||||
Item []MixedMsg `json:"item,omitempty"`
|
||||
} `json:"mixed,omitempty"` // 消息内容。可包含图片、文字、表情等多种消息。Object类型
|
||||
}
|
||||
|
||||
// MeetingVoiceCallMessage 音频存档消息
|
||||
type MeetingVoiceCallMessage struct {
|
||||
BaseMessage
|
||||
VoiceID string `json:"voiceid,omitempty"` // 音频id
|
||||
MeetingVoiceCall *MeetingVoiceCall `json:"meeting_voice_call,omitempty"` // 音频消息内容。包括结束时间、fileid,可能包括多个demofiledata、sharescreendata消息,demofiledata表示文档共享信息,sharescreendata表示屏幕共享信息。Object类型
|
||||
}
|
||||
|
||||
// VoipDocShareMessage 音频共享消息
|
||||
type VoipDocShareMessage struct {
|
||||
BaseMessage
|
||||
VoipID string `json:"voipid,omitempty"` // 音频id
|
||||
VoipDocShare *VoipDocShare `json:"voip_doc_share,omitempty"` // 共享文档消息内容。包括filename、md5sum、filesize、sdkfileid字段。Object类型
|
||||
}
|
||||
|
||||
// ExternalRedPacketMessage 互通小红包消息
|
||||
type ExternalRedPacketMessage struct {
|
||||
BaseMessage
|
||||
RedPacket struct {
|
||||
Type int32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||
Wish int32 `json:"wish,omitempty"` // 红包祝福语。String类型
|
||||
TotalCnt int32 `json:"totalcnt,omitempty"` // 红包总个数。Uint32类型
|
||||
TotalAmount int32 `json:"totalamount,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||
} `json:"redpacket,omitempty"`
|
||||
}
|
||||
|
||||
// SphFeedMessage 视频号消息
|
||||
type SphFeedMessage struct {
|
||||
BaseMessage
|
||||
SphFeed struct {
|
||||
FeedType string `json:"feed_type,omitempty"` // 视频号消息类型
|
||||
SphName string `json:"sph_name,omitempty"` // 视频号账号名称
|
||||
FeedDesc uint64 `json:"feed_desc,omitempty"` // 视频号账号名称
|
||||
}
|
||||
}
|
||||
|
||||
// SwitchMessage 企业切换日志
|
||||
type SwitchMessage struct {
|
||||
MsgID string `json:"msgid,omitempty"` // 消息id,消息的唯一标识,企业可以使用此字段进行消息去重
|
||||
Action string `json:"action,omitempty"` // 消息动作,切换企业为switch
|
||||
Time int64 `json:"time,omitempty"` // 消息发送时间戳,utc时间,ms单位。
|
||||
User string `json:"user,omitempty"` // 具体为切换企业的成员的userid。
|
||||
}
|
||||
|
||||
// ChatRecord 会话记录消息
|
||||
type ChatRecord struct {
|
||||
Type string `json:"type,omitempty"` // 每条聊天记录的具体消息类型:ChatRecordText/ ChatRecordFile/ ChatRecordImage/ ChatRecordVideo/ ChatRecordLink/ ChatRecordLocation/ ChatRecordMixed ….
|
||||
Content string `json:"content,omitempty"` // 消息内容。Json串,内容为对应类型的json
|
||||
MsgTime int64 `json:"msgtime,omitempty"` // 消息时间,utc时间,ms单位。
|
||||
FromChatroom bool `json:"from_chatroom,omitempty"` // 是否来自群会话。
|
||||
}
|
||||
|
||||
// CollectDetails 填表消息
|
||||
type CollectDetails struct {
|
||||
ID uint64 `json:"id,omitempty"` // 表项id
|
||||
Ques string `json:"ques,omitempty"` // 表项名称
|
||||
Type string `json:"type,omitempty"` // 表项类型,有Text(文本),Number(数字),Date(日期),Time(时间)
|
||||
}
|
||||
|
||||
// News 图文消息
|
||||
type News struct {
|
||||
Title string `json:"title,omitempty"` // 图文消息标题
|
||||
Desc string `json:"description,omitempty"` // 图文消息描述
|
||||
URL string `json:"url,omitempty"` // 图文消息点击跳转地址
|
||||
PicURL string `json:"picurl,omitempty"` // 图文消息配图的url
|
||||
}
|
||||
|
||||
// MixedMsg 混合消息
|
||||
type MixedMsg struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
// MeetingVoiceCall 音频存档消息
|
||||
type MeetingVoiceCall struct {
|
||||
EndTime int64 `json:"endtime,omitempty"` // 音频结束时间
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 音频媒体下载的id
|
||||
DemoFileData []DemoFileData `json:"demofiledata,omitempty"` // 文档分享对象,Object类型
|
||||
ShareScreenData []ShareScreenData `json:"sharescreendata,omitempty"` // 屏幕共享对象,Object类型
|
||||
}
|
||||
|
||||
// DemoFileData 文档共享消息
|
||||
type DemoFileData struct {
|
||||
FileName string `json:"filename,omitempty"` // 文档共享名称
|
||||
DemoOperator string `json:"demooperator,omitempty"` // 文档共享操作用户的id
|
||||
StartTime int64 `json:"starttime,omitempty"` // 文档共享开始时间
|
||||
EndTime int64 `json:"endtime,omitempty"` // 文档共享结束时间
|
||||
}
|
||||
|
||||
// ShareScreenData 屏幕共享信息
|
||||
type ShareScreenData struct {
|
||||
Share string `json:"share,omitempty"` // 屏幕共享用户的id
|
||||
StartTime int64 `json:"starttime,omitempty"` // 屏幕共享开始时间
|
||||
EndTime int64 `json:"endtime,omitempty"` // 屏幕共享结束时间
|
||||
}
|
||||
|
||||
// VoipDocShare 音频共享文档消息
|
||||
type VoipDocShare struct {
|
||||
FileName string `json:"filename,omitempty"` // 文档共享文件名称
|
||||
Md5Sum string `json:"md5sum,omitempty"` // 共享文件的md5值
|
||||
FileSize uint64 `json:"filesize,omitempty"` // 共享文件的大小
|
||||
SdkFileID string `json:"sdkfileid,omitempty"` // 共享文件的sdkfile,通过此字段进行媒体数据下载
|
||||
}
|
||||
Reference in New Issue
Block a user