1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-07 06:02:26 +08:00

企业微信内部开发API:消息推送与接收,以及回调处理

This commit is contained in:
hb
2021-11-24 14:18:10 +08:00
parent 73adb7dcdd
commit 7ae8e08a3e
10 changed files with 445 additions and 117 deletions

165
work/message/app.go Normal file
View File

@@ -0,0 +1,165 @@
package message
import (
"encoding/json"
"fmt"
"github.com/silenceper/wechat/v2/util"
"github.com/silenceper/wechat/v2/work/context"
)
const (
messageSendURL = "https://qyapi.weixin.qq.com/cgi-bin/message/send"
messageUpdateTemplateCardURL = "https://api.weixin.qq.com/cgi-bin/message/update_template_card"
messageDelURL = "https://api.weixin.qq.com/cgi-bin/message/recall"
)
//App 应用消息
type App struct {
*context.Context
}
//NewApp 实例化
func NewApp(context *context.Context) *App {
tpl := new(App)
tpl.Context = context
return tpl
}
//AppMessage 发送的模板消息内容
type AppMessage struct {
ToUser string `json:"touser"` // 必须, 成员ID列表多个接收者用|分隔最多支持1000个 ,指定为”@all”则向该企业应用的全部成员发送
Toparty string `json:"toparty"` //部门ID列表,当touser为”@all”时忽略本参数
Totag string `json:"totag"` //标签ID列表,当touser为”@all”时忽略本参数
Msgtype string `json:"msgtype"`
Agentid int `json:"agentid"`
Safe int `json:"safe"`
EnableIdTrans int `json:"enable_id_trans"`
EnableDuplicateCheck int `json:"enable_duplicate_check"`
DuplicateCheckInterval int `json:"duplicate_check_interval"`
Text *Text
*Image
*Voice
*Video
File *PushFile `json:"file"`
TextCard *PushTextCard `json:"textcard"`
News *News `json:"news"`
MpNews *MpNews `json:"mpnews"`
Markdown *Text `json:"markdown"`
//todo(hb1707) 可能会发生变化的字段直接用interface{}了
MiniprogramNotice interface{} `json:"miniprogram_notice"`
TemplateCard interface{} `json:"template_card"`
}
type PushFile struct {
MediaID string `json:"media_id"`
}
type PushTextCard struct {
Title string `json:"title"`
Description string `json:"description"`
Url string `json:"url"`
Btntxt string `json:"btntxt"`
}
type resTemplateSend struct {
util.CommonError
Invaliduser string `json:"invaliduser"` //不合法的userid不区分大小写统一转为小写
Invalidparty string `json:"invalidparty"` //不合法的partyid
Invalidtag string `json:"invalidtag"` //不合法的标签id
MsgID int64 `json:"msgid"` //消息id用于撤回应用消息
ResponseCode string `json:"response_code"` //仅消息类型为“按钮交互型”“投票选择型”和“多项选择型”的模板卡片消息返回应用可使用response_code调用更新模版卡片消息接口24小时内有效且只能使用一次
}
//Send 发送应用消息
func (tpl *App) Send(msg *AppMessage) (msgID int64, err error) {
var accessToken string
accessToken, err = tpl.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf("%s?access_token=%s", messageSendURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, msg)
if err != nil {
return
}
var result resTemplateSend
err = json.Unmarshal(response, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
err = fmt.Errorf("template msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
return
}
msgID = result.MsgID
return
}
//TemplateUpdate 更新模版卡片消息内容
type TemplateUpdate struct {
Userids []string `json:"userids"`
Partyids []int `json:"partyids"`
Tagids []int `json:"tagids"`
Atall int `json:"atall"`
Agentid int `json:"agentid"`
ResponseCode string `json:"response_code"`
*UpdateButton
*TemplateCard
}
//UpdateTemplate 更新模版卡片消息
func (tpl *App) UpdateTemplate(msg *TemplateUpdate) (msgID int64, err error) {
var accessToken string
accessToken, err = tpl.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf("%s?access_token=%s", messageUpdateTemplateCardURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, msg)
if err != nil {
return
}
var result resTemplateSend
err = json.Unmarshal(response, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
err = fmt.Errorf("template msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
return
}
msgID = result.MsgID
return
}
type ReqRecall struct {
MsgID int64 `json:"msgid"`
}
//Recall 撤回应用消息
func (tpl *App) Recall(msgID int64) (err error) {
var accessToken string
accessToken, err = tpl.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf("%s?access_token=%s", messageDelURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, &ReqRecall{
MsgID: msgID,
})
if err != nil {
return
}
var result util.CommonError
err = json.Unmarshal(response, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
err = fmt.Errorf("template msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
return
}
return
}

16
work/message/image.go Normal file
View File

@@ -0,0 +1,16 @@
package message
//Image 图片消息
type Image struct {
CommonToken `json:"-"`
Image struct {
MediaID string `xml:"MediaId" json:"media_id"`
} `xml:"Image" json:"image"`
}
//NewImage 回复图片消息
func NewImage(mediaID string) *Image {
image := new(Image)
image.Image.MediaID = mediaID
return image
}

View File

@@ -6,16 +6,19 @@ import (
"github.com/silenceper/wechat/v2/officialaccount/device"
)
// MsgType 基本消息类型
// MsgType 企业微信普通消息类型
type MsgType string
// EventType 事件类型
// EventType 企业微信事件消息类型
type EventType string
// InfoType 第三方平台授权事件类型
type InfoType string
const (
//MsgTypeEvent 表示事件推送消息 [限接收]
MsgTypeEvent = "event"
//MsgTypeText 表示文本消息
MsgTypeText MsgType = "text"
//MsgTypeImage 表示图片消息
@@ -24,37 +27,48 @@ const (
MsgTypeVoice = "voice"
//MsgTypeVideo 表示视频消息
MsgTypeVideo = "video"
//MsgTypeMiniprogrampage 表示小程序卡片消息
MsgTypeMiniprogrampage = "miniprogrampage"
//MsgTypeShortVideo 表示短视频消息[限接收]
MsgTypeShortVideo = "shortvideo"
//MsgTypeLocation 表示坐标消息[限接收]
MsgTypeLocation = "location"
//MsgTypeNews 表示图文消息[限回复与发送应用消息]
MsgTypeNews = "news"
//MsgTypeLink 表示链接消息[限接收]
MsgTypeLink = "link"
//MsgTypeMusic 表示音乐消息[限回复]
MsgTypeMusic = "music"
//MsgTypeNews 表示图文消息[限回复]
MsgTypeNews = "news"
//MsgTypeTransfer 表示消息消息转发到客服
MsgTypeTransfer = "transfer_customer_service"
//MsgTypeEvent 表示事件推送消息
MsgTypeEvent = "event"
//MsgTypeLocation 表示坐标消息[限接收]
MsgTypeLocation = "location"
//MsgTypeUpdateButton 更新点击用户的按钮文案[限回复应用消息]
MsgTypeUpdateButton = "update_button"
//MsgTypeUpdateTemplateCard 更新点击用户的整张卡片[限回复应用消息]
MsgTypeUpdateTemplateCard = "update_template_card"
//MsgTypeFile 文件消息[限发送应用消息]
MsgTypeFile = "file"
//MsgTypeTextCard 文本卡片消息[限发送应用消息]
MsgTypeTextCard = "textcard"
//MsgTypeMpNews 图文消息[限发送应用消息] 跟普通的图文消息一致,唯一的差异是图文内容存储在企业微信
MsgTypeMpNews = "mpnews"
//MsgTypeMarkdown markdown消息[限发送应用消息]
MsgTypeMarkdown = "markdown"
//MsgTypeMiniprogramNotice 小程序通知消息[限发送应用消息]
MsgTypeMiniprogramNotice = "miniprogram_notice"
//MsgTypeTemplateCard 模板卡片消息[限发送应用消息]
MsgTypeTemplateCard = "template_card"
)
const (
//EventSubscribe 订阅
//EventSubscribe 成员关注,成员已经加入企业,管理员添加成员到应用可见范围(或移除可见范围)时
EventSubscribe EventType = "subscribe"
//EventUnsubscribe 取消订阅
//EventUnsubscribe 成员取消关注,成员已经在应用可见范围,成员加入(或退出)企业时
EventUnsubscribe = "unsubscribe"
//EventScan 用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者
EventScan = "SCAN"
//EventEnterAgent 本事件在成员进入企业微信的应用时触发
EventEnterAgent = "enter_agent"
//EventLocation 上报地理位置事件
EventLocation = "LOCATION"
//EventBatchJobResult 异步任务完成事件推送
EventBatchJobResult = "batch_job_result"
//EventClick 点击菜单拉取消息时的事件推送
EventClick = "CLICK"
EventClick = "click"
//EventView 点击菜单跳转链接时的事件推送
EventView = "VIEW"
EventView = "view"
//EventScancodePush 扫码推事件的事件推送
EventScancodePush = "scancode_push"
//EventScancodeWaitmsg 扫码推事件且弹出“消息接收中”提示框的事件推送
@@ -67,106 +81,119 @@ const (
EventPicWeixin = "pic_weixin"
//EventLocationSelect 弹出地理位置选择器的事件推送
EventLocationSelect = "location_select"
//EventTemplateSendJobFinish 发送模板消息推送通知
EventTemplateSendJobFinish = "TEMPLATESENDJOBFINISH"
//EventMassSendJobFinish 群发消息推送通知
EventMassSendJobFinish = "MASSSENDJOBFINISH"
//EventWxaMediaCheck 异步校验图片/音频是否含有违法违规内容推送事件
EventWxaMediaCheck = "wxa_media_check"
//EventOpenApprovalChange 审批状态通知事件推送
EventOpenApprovalChange = "open_approval_change"
//EventShareAgentChange 共享应用事件回调
EventShareAgentChange = "share_agent_change"
//EventTemplateCard 模板卡片事件推送
EventTemplateCard = "template_card_event"
//EventTemplateCardMenu 通用模板卡片右上角菜单事件推送
EventTemplateCardMenu = "template_card_menu_event"
//EventChangeExternalContact 企业客户事件推送
//add_external_contact 添加
//edit_external_contact 编辑
//add_half_external_contact 免验证添加
//del_external_contact 员工删除客户
//del_follow_user 客户删除跟进员工
//transfer_fail 企业将客户分配给新的成员接替后,客户添加失败
//change_external_chat 客户群创建事件
EventChangeExternalContact = "change_external_contact"
//EventChangeExternalChat 企业客户群变更事件推送
//create 客户群创建
//update 客户群变更
//dismiss 客户群解散
EventChangeExternalChat = "change_external_chat"
//EventChangeExternalTag 企业客户标签创建事件推送
//create 创建标签
//update 变更标签
//delete 删除标签
//shuffle 重新排序
EventChangeExternalTag = "change_external_tag"
//EventKfMsg 企业微信客服回调事件
EventKfMsg = "kf_msg_or_event"
//EventLivingStatusChange 直播回调事件
EventLivingStatusChange = "living_status_change"
//EventMsgauditNotify 会话内容存档开启后,产生会话回调事件
EventMsgauditNotify = "msgaudit_notify"
)
const (
//微信开放平台需要用到
//todo 第三方应用开发
/*const (
//微信开放平台需要用到
// InfoTypeVerifyTicket 返回ticket
InfoTypeVerifyTicket InfoType = "component_verify_ticket"
// InfoTypeAuthorized 授权
InfoTypeAuthorized = "authorized"
// InfoTypeUnauthorized 取消授权
InfoTypeUnauthorized = "unauthorized"
// InfoTypeUpdateAuthorized 更新授权
InfoTypeUpdateAuthorized = "updateauthorized"
)
// InfoTypeVerifyTicket 返回ticket
InfoTypeVerifyTicket InfoType = "component_verify_ticket"
// InfoTypeAuthorized 授权
InfoTypeAuthorized = "authorized"
// InfoTypeUnauthorized 取消授权
InfoTypeUnauthorized = "unauthorized"
// InfoTypeUpdateAuthorized 更新授权
InfoTypeUpdateAuthorized = "updateauthorized"
)*/
//MixMessage 存放所有微信发送过来的消息和事件
//MixMessage 存放所有企业微信官方发送过来的消息和事件
type MixMessage struct {
CommonToken
//基本消息
MsgID int64 `xml:"MsgId"` //其他消息推送过来是MsgId
TemplateMsgID int64 `xml:"MsgID"` //模板消息推送成功的消息是MsgID
Content string `xml:"Content"`
Recognition string `xml:"Recognition"`
PicURL string `xml:"PicUrl"`
MediaID string `xml:"MediaId"`
Format string `xml:"Format"`
ThumbMediaID string `xml:"ThumbMediaId"`
LocationX float64 `xml:"Location_X"`
LocationY float64 `xml:"Location_Y"`
Scale float64 `xml:"Scale"`
Label string `xml:"Label"`
Title string `xml:"Title"`
Description string `xml:"Description"`
URL string `xml:"Url"`
//接收普通消息
MsgID int64 `xml:"MsgId"` //其他消息推送过来是MsgId
AgentID int `xml:"AgentID"` //企业应用的id整型。可在应用的设置页面查看
Content string `xml:"Content"` //文本消息内容
Format string `xml:"Format"` //语音消息格式如amrspeex等
ThumbMediaID string `xml:"ThumbMediaId"` //视频消息缩略图的媒体id可以调用获取媒体文件接口拉取数据仅三天内有效
Title string `xml:"Title"` //链接消息,标题
Description string `xml:"Description"` //链接消息,描述
URL string `xml:"Url"` //链接消息链接跳转的url
PicURL string `xml:"PicUrl"` ////图片消息或者链接消息封面缩略图的url
MediaID string `xml:"MediaId"` //图片媒体文件id//语音媒体文件id//视频消息缩略图的媒体id可以调用获取媒体文件接口拉取仅三天内有效
LocationX float64 `xml:"Location_X"` //位置消息,地理位置纬度
LocationY float64 `xml:"Location_Y"` //位置消息,地理位置经度
Scale float64 `xml:"Scale"` //位置消息,地图缩放大小
Label string `xml:"Label"` //位置消息,地理位置信息
AppType string `xml:"AppType"` //接收地理位置时存在app类型在企业微信固定返回wxwork在微信不返回该字段
//TemplateMsgID int64 `xml:"MsgID"` //模板消息推送成功的消息是MsgID
///Recognition string `xml:"Recognition"`
//事件相关
Event EventType `xml:"Event"`
EventKey string `xml:"EventKey"`
Ticket string `xml:"Ticket"`
Latitude string `xml:"Latitude"`
Longitude string `xml:"Longitude"`
Precision string `xml:"Precision"`
MenuID string `xml:"MenuId"`
Status string `xml:"Status"`
SessionFrom string `xml:"SessionFrom"`
TotalCount int64 `xml:"TotalCount"`
FilterCount int64 `xml:"FilterCount"`
SentCount int64 `xml:"SentCount"`
ErrorCount int64 `xml:"ErrorCount"`
Event EventType `xml:"Event"`
EventKey string `xml:"EventKey"`
ScanCodeInfo struct {
ScanType string `xml:"ScanType"`
ScanResult string `xml:"ScanResult"`
} `xml:"ScanCodeInfo"`
//仅上报地理位置事件
Latitude string `xml:"Latitude"` //地理位置纬度
Longitude string `xml:"Longitude"` //地理位置经度
Precision string `xml:"Precision"` //地理位置精度
SendPicsInfo struct {
Count int32 `xml:"Count"`
PicList []EventPic `xml:"PicList>item"`
} `xml:"SendPicsInfo"`
//仅异步任务完成事件
JobId string `xml:"JobId"` //异步任务id最大长度为64字符
JobType string `xml:"JobType"` //异步任务操作类型字符串目前分别有sync_user(增量更新成员)、 replace_user(全量覆盖成员、invite_user(邀请成员关注、replace_party(全量覆盖部门)
ErrCode int `xml:"ErrCode"` //异步任务,返回码
ErrMsg string `xml:"ErrMsg"` //异步任务,对返回码的文本描述内容
SendLocationInfo struct {
LocationX float64 `xml:"Location_X"`
LocationY float64 `xml:"Location_Y"`
Scale float64 `xml:"Scale"`
Label string `xml:"Label"`
Poiname string `xml:"Poiname"`
}
//开启通讯录回调通知 https://open.work.weixin.qq.com/api/doc/90000/90135/90967
// 第三方平台相关
InfoType InfoType `xml:"InfoType"`
AppID string `xml:"AppId"`
ComponentVerifyTicket string `xml:"ComponentVerifyTicket"`
AuthorizerAppid string `xml:"AuthorizerAppid"`
AuthorizationCode string `xml:"AuthorizationCode"`
AuthorizationCodeExpiredTime int64 `xml:"AuthorizationCodeExpiredTime"`
PreAuthCode string `xml:"PreAuthCode"`
// 卡券相关
CardID string `xml:"CardId"`
RefuseReason string `xml:"RefuseReason"`
IsGiveByFriend int32 `xml:"IsGiveByFriend"`
FriendUserName string `xml:"FriendUserName"`
UserCardCode string `xml:"UserCardCode"`
OldUserCardCode string `xml:"OldUserCardCode"`
OuterStr string `xml:"OuterStr"`
IsRestoreMemberCard int32 `xml:"IsRestoreMemberCard"`
UnionID string `xml:"UnionId"`
// 内容审核相关
IsRisky bool `xml:"isrisky"`
ExtraInfoJSON string `xml:"extra_info_json"`
TraceID string `xml:"trace_id"`
StatusCode int `xml:"status_code"`
// todo 第三方平台相关 字段名可能不准确
/*InfoType InfoType `xml:"InfoType"`
AppID string `xml:"AppId"`
ComponentVerifyTicket string `xml:"ComponentVerifyTicket"`
AuthorizerAppid string `xml:"AuthorizerAppid"`
AuthorizationCode string `xml:"AuthorizationCode"```````````````````````````````````````
AuthorizationCodeExpiredTime int64 `xml:"AuthorizationCodeExpiredTime"`
PreAuthCode string `xml:"PreAuthCode"`*/
//设备相关
device.MsgDevice
@@ -181,6 +208,7 @@ type EventPic struct {
type EncryptedXMLMsg struct {
XMLName struct{} `xml:"xml" json:"-"`
ToUserName string `xml:"ToUserName" json:"ToUserName"`
AgentID string `xml:"AgentID" json:"AgentID"`
EncryptedMsg string `xml:"Encrypt" json:"Encrypt"`
}

41
work/message/news.go Normal file
View File

@@ -0,0 +1,41 @@
package message
//News 图文消息
type News struct {
CommonToken `json:"-"`
ArticleCount int `xml:"ArticleCount" json:"-"`
Articles []*Article `xml:"Articles>item,omitempty" json:"articles"`
}
//NewNews 初始化图文消息
func NewNews(articles []*Article) *News {
news := new(News)
news.ArticleCount = len(articles)
news.Articles = articles
return news
}
//Article 单篇文章
type Article struct {
Title string `xml:"Title,omitempty" json:"title"`
Description string `xml:"Description,omitempty" json:"description"`
PicURL string `xml:"PicUrl,omitempty" json:"picurl"`
URL string `xml:"Url,omitempty" json:"url"`
Appid string `xml:"-" json:"appid"` //仅在发送应用消息时需要
Pagepath string `xml:"-" json:"pagepath"` //仅在发送应用消息时需要
}
//MpNews 图文消息
type MpNews struct {
Articles []*MpNewsArticle `xml:"-" json:"articles"`
}
//MpNewsArticle mpnews类型的图文消息跟普通的图文消息一致唯一的差异是图文内容存储在企业微信
type MpNewsArticle struct {
Title string `json:"title"`
ThumbMediaId string `json:"thumb_media_id"`
Author string `json:"author"`
ContentSourceUrl string `json:"content_source_url"`
Content string `json:"content"`
Digest string `json:"digest"`
}

View File

@@ -6,7 +6,7 @@ import "errors"
var ErrInvalidReply = errors.New("无效的回复消息")
//ErrUnsupportReply 不支持的回复类型
var ErrUnsupportReply = errors.New("不支持的回复消息")
var ErrUnsupportReply = errors.New("无需回复消息")
//Reply 消息回复
type Reply struct {

View File

@@ -0,0 +1,30 @@
package message
//UpdateButton 模板卡片按钮
type UpdateButton struct {
CommonToken `json:"-"`
Button struct {
ReplaceName string `xml:"ReplaceName" json:"replace_name"`
} `xml:"Button" json:"button"`
}
//NewUpdateButton 更新点击用户的按钮文案
func NewUpdateButton(replaceName string) *UpdateButton {
btn := new(UpdateButton)
btn.Button.ReplaceName = replaceName
return btn
}
//TemplateCard 被动回复模板卡片
//https://open.work.weixin.qq.com/api/doc/90000/90135/90241
type TemplateCard struct {
CommonToken `json:"-"`
TemplateCard interface{} `xml:"TemplateCard" json:"template_card"`
}
// NewTemplateCard 更新点击用户的整张卡片
func NewTemplateCard(cardXml interface{}) *TemplateCard {
card := new(TemplateCard)
card.TemplateCard = cardXml
return card
}

14
work/message/text.go Normal file
View File

@@ -0,0 +1,14 @@
package message
//Text 文本消息
type Text struct {
CommonToken `json:"-"`
Content CDATA `json:"content" xml:"Content"`
}
//NewText 初始化文本消息
func NewText(content string) *Text {
text := new(Text)
text.Content = CDATA(content)
return text
}

20
work/message/video.go Normal file
View File

@@ -0,0 +1,20 @@
package message
//Video 视频消息
type Video struct {
CommonToken `json:"-"`
Video struct {
MediaID string `xml:"MediaId" json:"media_id"`
Title string `xml:"Title,omitempty" json:"title"`
Description string `xml:"Description,omitempty" json:"description"`
} `xml:"Video" json:"video"`
}
//NewVideo 回复图片消息
func NewVideo(mediaID, title, description string) *Video {
video := new(Video)
video.Video.MediaID = mediaID
video.Video.Title = title
video.Video.Description = description
return video
}

16
work/message/voice.go Normal file
View File

@@ -0,0 +1,16 @@
package message
//Voice 语音消息
type Voice struct {
CommonToken `json:"-"`
Voice struct {
MediaID string `xml:"MediaId" json:"media_id"`
} `xml:"Voice" json:"voice"`
}
//NewVoice 回复语音消息
func NewVoice(mediaID string) *Voice {
voice := new(Voice)
voice.Voice.MediaID = mediaID
return voice
}

View File

@@ -64,7 +64,7 @@ func (srv *Server) SkipValidate(skip bool) {
srv.skipValidate = skip
}
//Serve 处理微信的请求消息
//Serve 处理企业微信的请求消息
func (srv *Server) Serve() error {
response, err := srv.handleRequest()
if err != nil {
@@ -88,7 +88,7 @@ func (srv *Server) Validate() bool {
return signature == util.Signature(srv.Token, timestamp, nonce)
}
//HandleRequest 处理微信的请求
//HandleRequest 处理企业微信的请求
func (srv *Server) handleRequest() (reply *message.Reply, err error) {
var msg interface{}
@@ -105,7 +105,7 @@ func (srv *Server) handleRequest() (reply *message.Reply, err error) {
return
}
//getMessage 解析微信返回的消息
//getMessage 解析企业微信返回的消息
func (srv *Server) getMessage() (interface{}, error) {
var rawXMLMsgBytes []byte
var err error
@@ -136,7 +136,6 @@ func (srv *Server) getMessage() (interface{}, error) {
}
srv.RequestRawXMLMsg = rawXMLMsgBytes
return srv.parseRequestMessage(rawXMLMsgBytes)
}
@@ -167,9 +166,9 @@ func (srv *Server) buildResponse(reply *message.Reply) (err error) {
case message.MsgTypeImage:
case message.MsgTypeVoice:
case message.MsgTypeVideo:
case message.MsgTypeMusic:
case message.MsgTypeNews:
case message.MsgTypeTransfer:
case message.MsgTypeUpdateButton:
case message.MsgTypeUpdateTemplateCard:
default:
err = message.ErrUnsupportReply
return
@@ -195,7 +194,6 @@ func (srv *Server) buildResponse(reply *message.Reply) (err error) {
params[0] = reflect.ValueOf(util.GetCurrTS())
value.MethodByName("SetCreateTime").Call(params)
srv.ResponseMsg = msgData
srv.ResponseRawXMLMsg, err = xml.Marshal(msgData)
return