diff --git a/src/channels/eCommerce/application.go b/src/channels/eCommerce/application.go new file mode 100644 index 00000000..60e03043 --- /dev/null +++ b/src/channels/eCommerce/application.go @@ -0,0 +1,194 @@ +package eCommerce + +import ( + "github.com/ArtisanCloud/PowerLibs/v3/logger" + "github.com/ArtisanCloud/PowerLibs/v3/logger/contract" + "github.com/ArtisanCloud/PowerLibs/v3/object" + "github.com/ArtisanCloud/PowerWeChat/v3/src/channels/eCommerce/store" + "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel" + "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/providers" + "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram/auth" + "net/http" +) + +type ECommerce struct { + *kernel.ServiceContainer + + Config *kernel.Config + AccessToken *auth.AccessToken + + Store *store.Client + + Logger *logger.Logger +} + +type UserConfig struct { + AppID string + Secret string + + StableTokenMode bool + ForceRefresh bool + RefreshToken string + ComponentAppID string + ComponentAppToken string + Token string + AESKey string + + ResponseType string + Log Log + OAuth OAuth + Cache kernel.CacheInterface + + Http Http + + HttpDebug bool + Debug bool + NotifyURL string + Sandbox bool +} + +type Http struct { + Timeout float64 + BaseURI string + ProxyURI string + Transport http.RoundTripper +} + +type Log struct { + Driver contract.LoggerInterface + Level string + File string + Error string + ENV string + Stdout bool +} + +type OAuth struct { + Callback string + Scopes []string +} + +func NewECommerce(config *UserConfig, extraInfos ...*kernel.ExtraInfo) (*ECommerce, error) { + var err error + + userConfig, err := MapUserConfig(config) + if err != nil { + return nil, err + } + + var extraInfo, _ = kernel.NewExtraInfo() + if len(extraInfos) > 0 { + extraInfo = extraInfos[0] + } + + // init an app container + container, err := kernel.NewServiceContainer(userConfig, extraInfo) + if err != nil { + return nil, err + } + container.GetConfig() + + // init app + app := &ECommerce{ + ServiceContainer: container, + } + + //-------------- global app config -------------- + // global app config + app.Config = providers.RegisterConfigProvider(app) + + app.Logger, err = logger.NewLogger(app.Config.Get("log.driver", nil), &object.HashMap{ + "level": app.Config.GetString("log.level", "info"), + "env": app.Config.GetString("log.env", "develop"), + "outputPath": app.Config.GetString("log.file", "./wechat/info.log"), + "errorPath": app.Config.GetString("log.error", "./wechat/error.log"), + "stdout": app.Config.GetBool("log.stdout", false), + }) + if err != nil { + return nil, err + } + + //-------------- register auth,AccessToken -------------- + app.AccessToken, err = auth.RegisterProvider(app) + if err != nil { + return nil, err + } + + return app, err +} + +func (app *ECommerce) GetContainer() *kernel.ServiceContainer { + return app.ServiceContainer +} + +func (app *ECommerce) GetAccessToken() *kernel.AccessToken { + return app.AccessToken.AccessToken +} + +func (app *ECommerce) GetConfig() *kernel.Config { + return app.Config +} + +func (app *ECommerce) GetComponent(name string) interface{} { + + switch name { + case "AccessToken": + return app.AccessToken + case "Config": + return app.Config + + case "Store": + return app.Store + + case "Logger": + return app.Logger + + default: + return nil + } + +} + +func MapUserConfig(userConfig *UserConfig) (*object.HashMap, error) { + + baseURI := "https://api.weixin.qq.com/" + if userConfig.Http.BaseURI != "" { + baseURI = userConfig.Http.BaseURI + } + + config := &object.HashMap{ + + "app_id": userConfig.AppID, + "secret": userConfig.Secret, + + "token": userConfig.Token, + "aes_key": userConfig.AESKey, + "component_app_id": userConfig.ComponentAppID, + "component_app_token": userConfig.ComponentAppToken, + "stable_token_mode": userConfig.StableTokenMode, + "refresh_token": userConfig.RefreshToken, + + "response_type": userConfig.ResponseType, + "http": &object.HashMap{ + "timeout": userConfig.Http.Timeout, + "base_uri": baseURI, + "proxy_uri": userConfig.Http.ProxyURI, + "transport": userConfig.Http.Transport, + }, + "log": &object.HashMap{ + "driver": userConfig.Log.Driver, + "level": userConfig.Log.Level, + "file": userConfig.Log.File, + "error": userConfig.Log.Error, + "env": userConfig.Log.ENV, + "stdout": userConfig.Log.Stdout, + }, + "cache": userConfig.Cache, + + "http_debug": userConfig.HttpDebug, + "debug": userConfig.Debug, + } + + return config, nil + +} diff --git a/src/channels/eCommerce/store/client.go b/src/channels/eCommerce/store/client.go new file mode 100644 index 00000000..944318ea --- /dev/null +++ b/src/channels/eCommerce/store/client.go @@ -0,0 +1,40 @@ +package store + +import ( + "context" + "github.com/ArtisanCloud/PowerLibs/v3/object" + "github.com/ArtisanCloud/PowerWeChat/v3/src/channels/eCommerce/store/request" + "github.com/ArtisanCloud/PowerWeChat/v3/src/channels/eCommerce/store/response" + "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel" +) + +type Client struct { + BaseClient *kernel.BaseClient +} + +// 获取店铺基本信息 +// https://developers.weixin.qq.com/doc/store/shop/API/basics/getbasicinfo.html +func (comp *Client) GetBasicInfo(ctx context.Context) (*response.ResponseGetBasicInfo, error) { + + result := &response.ResponseGetBasicInfo{} + + _, err := comp.BaseClient.HttpGet(ctx, "channels/ec/basics/info/get", nil, nil, result) + + return result, err +} + +// 获取店铺二维码 +// https://developers.weixin.qq.com/doc/store/shop/API/basics/getshopqrcode.html +func (comp *Client) GetShopQRCode(ctx context.Context, data *request.RequestGetShopQRCode) (*response.ResponseGetShopQRCode, error) { + + result := &response.ResponseGetShopQRCode{} + + params, err := object.StructToHashMap(data) + if err != nil { + return nil, err + } + + _, err = comp.BaseClient.HttpPost(ctx, "channels/ec/basics/shop/qrcode/get", params, nil, result) + + return result, err +} diff --git a/src/channels/eCommerce/store/provider.go b/src/channels/eCommerce/store/provider.go new file mode 100644 index 00000000..3d608a73 --- /dev/null +++ b/src/channels/eCommerce/store/provider.go @@ -0,0 +1,14 @@ +package store + +import "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel" + +func RegisterProvider(app kernel.ApplicationInterface) (*Client, error) { + baseClient, err := kernel.NewBaseClient(app, nil) + if err != nil { + return nil, err + } + return &Client{ + baseClient, + }, nil + +} diff --git a/src/channels/eCommerce/store/request/request.go b/src/channels/eCommerce/store/request/request.go new file mode 100644 index 00000000..f5aa1836 --- /dev/null +++ b/src/channels/eCommerce/store/request/request.go @@ -0,0 +1,6 @@ +package request + +type RequestGetShopQRCode struct { + WeComCorpId string `json:"wecom_corp_id"` + WeComUserId string `json:"wecom_user_id"` +} diff --git a/src/channels/eCommerce/store/response/response.go b/src/channels/eCommerce/store/response/response.go new file mode 100644 index 00000000..57adf1c0 --- /dev/null +++ b/src/channels/eCommerce/store/response/response.go @@ -0,0 +1,21 @@ +package response + +import "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/response" + +type Info struct { + Nickname string `json:"nickname"` + HeadImgUrl string `json:"headimg_url"` + SubjectType string `json:"subject_type"` + Status string `json:"status"` + Username string `json:"username"` +} + +type ResponseGetBasicInfo struct { + response.ResponseECommerce + Info Info `json:"info"` +} + +type ResponseGetShopQRCode struct { + response.ResponseECommerce + ShopQrcode string `json:"shop_qrcode"` +} diff --git a/src/kernel/response/wx.go b/src/kernel/response/wx.go index c19b79d5..4a09ca60 100644 --- a/src/kernel/response/wx.go +++ b/src/kernel/response/wx.go @@ -79,3 +79,10 @@ const ( //func (res *ResponseWork) GetStatusCode() int { // return 200 //} + +type ResponseECommerce struct { + ResponseBase + + ErrCode int `json:"errcode,omitempty"` + ErrMsg string `json:"errmsg,omitempty"` +} diff --git a/src/work/server/handlers/models/event.go b/src/work/server/handlers/models/event.go index 619ceae8..8a7ea930 100644 --- a/src/work/server/handlers/models/event.go +++ b/src/work/server/handlers/models/event.go @@ -32,32 +32,32 @@ const ( type EventSubscribe struct { contract.EventInterface models.CallbackMessageHeader - AgentID string `xml:"AgentID"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventEnterAgent struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventLocation struct { contract.EventInterface models.CallbackMessageHeader - Latitude string `xml:"Latitude"` - Longitude string `xml:"Longitude"` - Precision string `xml:"Precision"` - AgentID string `xml:"AgentID"` - AppType string `xml:"AppType"` + Latitude string `xml:"Latitude" json:"Latitude"` + Longitude string `xml:"Longitude" json:"Longitude"` + Precision string `xml:"Precision" json:"Precision"` + AgentID string `xml:"AgentID" json:"AgentID"` + AppType string `xml:"AppType" json:"AppType"` } type BatchJob struct { - Text string `xml:",chardata"` - JobID string `xml:"JobId"` - JobType string `xml:"JobType"` - ErrCode string `xml:"ErrCode"` - ErrMsg string `xml:"ErrMsg"` + Text string `xml:",chardata" json:",chardata"` + JobID string `xml:"JobId" json:"JobId"` + JobType string `xml:"JobType" json:"JobType"` + ErrCode string `xml:"ErrCode" json:"ErrCode"` + ErrMsg string `xml:"ErrMsg" json:"ErrMsg"` } type EventBatchJobResult struct { @@ -69,212 +69,260 @@ type EventBatchJobResult struct { type EventClick struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventView struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventScanCodePush struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - ScanCodeInfo *ScanCodeInfo `xml:"ScanCodeInfo"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + ScanCodeInfo *ScanCodeInfo `xml:"ScanCodeInfo" json:"ScanCodeInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` } type ScanCodeInfo struct { - Text string `xml:",chardata"` - ScanType string `xml:"ScanType"` - ScanResult string `xml:"ScanResult"` + Text string `xml:",chardata" json:",chardata"` + ScanType string `xml:"ScanType" json:"ScanType"` + ScanResult string `xml:"ScanResult" json:"ScanResult"` } type EventScancodeWaitMsg struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - ScanCodeInfo *ScanCodeInfo `xml:"ScanCodeInfo"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + ScanCodeInfo *ScanCodeInfo `xml:"ScanCodeInfo" json:"ScanCodeInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventPicSysPhoto struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - SendPicsInfo *SendPicsInfo `xml:"SendPicsInfo"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + SendPicsInfo *SendPicsInfo `xml:"SendPicsInfo" json:"SendPicsInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventPicPhotoOrAlbum struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - SendPicsInfo *SendPicsInfo `xml:"SendPicsInfo"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + SendPicsInfo *SendPicsInfo `xml:"SendPicsInfo" json:"SendPicsInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` } type Item struct { - Text string `xml:",chardata"` - PicMd5Sum string `xml:"PicMd5Sum"` + Text string `xml:",chardata" json:",chardata"` + PicMd5Sum string `xml:"PicMd5Sum" json:"PicMd5Sum"` } type PicList struct { - Text string `xml:",chardata"` - Item *Item `xml:"item"` + Text string `xml:",chardata" json:",chardata"` + Item *Item `xml:"item" json:"item"` } type SendPicsInfo struct { - Text string `xml:",chardata"` - Count string `xml:"Count"` - PicList *PicList `xml:"PicList"` + Text string `xml:",chardata" json:",chardata"` + Count string `xml:"Count" json:"Count"` + PicList *PicList `xml:"PicList" json:"PicList"` } type EventPicWeixin struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - SendPicsInfo SendPicsInfo `xml:"SendPicsInfo"` - AgentID string `xml:"AgentID"` + EventKey string `xml:"EventKey" json:"EventKey"` + SendPicsInfo SendPicsInfo `xml:"SendPicsInfo" json:"SendPicsInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` } type SendLocationInfo struct { - Text string `xml:",chardata"` - LocationX string `xml:"Location_X"` - LocationY string `xml:"Location_Y"` - Scale string `xml:"Scale"` - Label string `xml:"Label"` - PoiName string `xml:"Poiname"` + Text string `xml:",chardata" json:",chardata"` + LocationX string `xml:"Location_X" json:"Location_X"` + LocationY string `xml:"Location_Y" json:"Location_Y"` + Scale string `xml:"Scale" json:"Scale"` + Label string `xml:"Label" json:"Label"` + PoiName string `xml:"Poiname" json:"Poiname"` } type EventLocationSelect struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - SendLocationInfo *SendLocationInfo `xml:"SendLocationInfo"` - AgentID string `xml:"AgentID"` - AppType string `xml:"AppType"` + EventKey string `xml:"EventKey" json:"EventKey"` + SendLocationInfo *SendLocationInfo `xml:"SendLocationInfo" json:"SendLocationInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` + AppType string `xml:"AppType" json:"AppType"` } // ---------------------------------------------------------------------------- type Applier struct { - Text string `xml:",chardata"` - UserID string `xml:"UserId"` - Party string `xml:"Party"` + Text string `xml:",chardata" json:",chardata"` + UserID string `xml:"UserId" json:"UserId"` + Party string `xml:"Party" json:"Party"` } type Approver struct { - Text string `xml:",chardata"` - UserID string `xml:"UserId"` + Text string `xml:",chardata" json:",chardata"` + UserID string `xml:"UserId" json:"UserId"` } type Detail struct { - Text string `xml:",chardata"` - Approver *Approver `xml:"Approver"` - Speech string `xml:"Speech"` - SpStatus string `xml:"SpStatus"` - SpTime string `xml:"SpTime"` + Text string `xml:",chardata" json:",chardata"` + Approver *Approver `xml:"Approver" json:"Approver"` + Speech string `xml:"Speech" json:"Speech"` + SpStatus string `xml:"SpStatus" json:"SpStatus"` + SpTime string `xml:"SpTime" json:"SpTime"` } type SPRecord struct { - Text string `xml:",chardata"` - SpStatus string `xml:"SpStatus"` - ApproverAttr string `xml:"ApproverAttr"` - Details []Detail `xml:"Details"` + Text string `xml:",chardata" json:",chardata"` + SpStatus string `xml:"SpStatus" json:"SpStatus"` + ApproverAttr string `xml:"ApproverAttr" json:"ApproverAttr"` + Details []Detail `xml:"Details" json:"Details"` } type Notifier struct { - Text string `xml:",chardata"` - UserID string `xml:"UserId"` + Text string `xml:",chardata" json:",chardata"` + UserID string `xml:"UserId" json:"UserId"` } type CommentUserInfo struct { - Text string `xml:",chardata"` - UserID string `xml:"UserId"` + Text string `xml:",chardata" json:",chardata"` + UserID string `xml:"UserId" json:"UserId"` } type Comments struct { - Text string `xml:",chardata"` - CommentUserInfo *CommentUserInfo `xml:"CommentUserInfo"` - CommentTime string `xml:"CommentTime"` - CommentContent string `xml:"CommentContent"` - CommentID string `xml:"CommentId"` + Text string `xml:",chardata" json:",chardata"` + CommentUserInfo *CommentUserInfo `xml:"CommentUserInfo" json:"CommentUserInfo"` + CommentTime string `xml:"CommentTime" json:"CommentTime"` + CommentContent string `xml:"CommentContent" json:"CommentContent"` + CommentID string `xml:"CommentId" json:"CommentId"` +} + +type ApprovalNode struct { + NodeStatus int `xml:"NodeStatus" json:"NodeStatus"` + NodeAttr int `xml:"NodeAttr" json:"NodeAttr"` + NodeType int `xml:"NodeType" json:"NodeType"` + ApprovalItems ApprovalItems `xml:"Items" json:"Items"` +} + +type ApprovalItems struct { + ApprovalItem []ApprovalItem `xml:"Item" json:"Item"` +} + +type ApprovalItem struct { + ItemName string `xml:"ItemName" json:"ItemName"` + ItemUserId string `xml:"ItemUserId" json:"ItemUserId"` + ItemImage string `xml:"ItemImage" json:"ItemImage"` + ItemStatus int `xml:"ItemStatus" json:"ItemStatus"` + ItemSpeech string `xml:"ItemSpeech" json:"ItemSpeech"` + ItemOpTime int64 `xml:"ItemOpTime" json:"ItemOpTime"` +} + +type NotifyNodes struct { + NotifyNode []NotifyNode `xml:"NotifyNode" json:"NotifyNode"` +} + +type NotifyNode struct { + ItemName string `xml:"ItemName" json:"ItemName"` + ItemUserId string `xml:"ItemUserId" json:"ItemUserId"` + ItemImage string `xml:"ItemImage" json:"ItemImage"` +} + +type ApprovalNodes struct { + ApprovalNode []ApprovalNode `xml:"ApprovalNode" json:"ApprovalNode"` } type ApprovalInfo struct { - Text string `xml:",chardata"` - SpNO string `xml:"SpNo"` - SpName string `xml:"SpName"` - SpStatus string `xml:"SpStatus"` - TemplateID string `xml:"TemplateId"` - ApplyTime string `xml:"ApplyTime"` - Applier *Applier `xml:"Applyer"` - SpRecord []*SPRecord `xml:"SpRecord"` - Notifier *Notifier `xml:"Notifyer"` - Comments *Comments `xml:"Comments"` - StatusChangeEvent string `xml:"StatuChangeEvent"` + Text string `xml:",chardata" json:",chardata"` + SpNO string `xml:"SpNo" json:"SpNo"` + SpName string `xml:"SpName" json:"SpName"` + SpStatus string `xml:"SpStatus" json:"SpStatus"` + TemplateID string `xml:"TemplateId" json:"TemplateId"` + ApplyTime string `xml:"ApplyTime" json:"ApplyTime"` + Applier *Applier `xml:"Applyer" json:"Applyer"` + SpRecord []*SPRecord `xml:"SpRecord" json:"SpRecord"` + Notifier *Notifier `xml:"Notifyer" json:"Notifyer"` + Comments *Comments `xml:"Comments" json:"Comments"` + StatusChangeEvent string `xml:"StatuChangeEvent" json:"StatuChangeEvent"` + + // new fields + // https://developer.work.weixin.qq.com/document/path/90240#%E5%AE%A1%E6%89%B9%E7%8A%B6%E6%80%81%E9%80%9A%E7%9F%A5%E4%BA%8B%E4%BB%B6 + ThirdNo string `xml:"ThirdNo" json:"ThirdNo"` + OpenSpName string `xml:"OpenSpName" json:"OpenSpName"` + OpenTemplateId string `xml:"OpenTemplateId" json:"OpenTemplateId"` + OpenSpStatus int `xml:"OpenSpStatus" json:"OpenSpStatus"` + ApplyUserName string `xml:"ApplyUserName" json:"ApplyUserName"` + ApplyUserId string `xml:"ApplyUserId" json:"ApplyUserId"` + ApplyUserParty string `xml:"ApplyUserParty" json:"ApplyUserParty"` + ApplyUserImage string `xml:"ApplyUserImage" json:"ApplyUserImage"` + ApprovalNodes ApprovalNodes `xml:"ApprovalNodes" json:"ApprovalNodes"` + NotifyNodes NotifyNodes `xml:"NotifyNodes" json:"NotifyNodes"` + ApproverStep int `xml:"approverstep" json:"approverstep"` } type EventOpenApprovalChange struct { contract.EventInterface models.CallbackMessageHeader - AgentID string `xml:"AgentID"` - ApprovalInfo *ApprovalInfo `xml:"ApprovalInfo"` + AgentID string `xml:"AgentID" json:"AgentID"` + ApprovalInfo *ApprovalInfo `xml:"ApprovalInfo" json:"ApprovalInfo"` } type EventShareAgentChange struct { contract.EventInterface models.CallbackMessageHeader - AgentID string `xml:"AgentID"` + AgentID string `xml:"AgentID" json:"AgentID"` } // ---------------------------------------------------------------------------- type OptionID struct { - Text string `xml:",chardata"` - OptionID []string `xml:"OptionId"` + Text string `xml:",chardata" json:",chardata"` + OptionID []string `xml:"OptionId" json:"OptionId"` } type SelectItem struct { - Text string `xml:",chardata"` - QuestionKey string `xml:"QuestionKey"` - OptionIDs *OptionID `xml:"OptionIds"` + Text string `xml:",chardata" json:",chardata"` + QuestionKey string `xml:"QuestionKey" json:"QuestionKey"` + OptionIDs *OptionID `xml:"OptionIds" json:"OptionIds"` } type SelectItems struct { - Text string `xml:",chardata"` - SelectedItem []*SelectItem `xml:"SelectedItem"` + Text string `xml:",chardata" json:",chardata"` + SelectedItem []*SelectItem `xml:"SelectedItem" json:"SelectedItem"` } type EventTemplateCardEvent struct { contract.EventInterface models.CallbackMessageHeader - EventKey string `xml:"EventKey"` - TaskID string `xml:"TaskId"` - CardType string `xml:"CardType"` - ResponseCode string `xml:"ResponseCode"` - AgentID string `xml:"AgentID"` - SelectedItems *SelectItems `xml:"SelectedItems"` + EventKey string `xml:"EventKey" json:"EventKey"` + TaskID string `xml:"TaskId" json:"TaskId"` + CardType string `xml:"CardType" json:"CardType"` + ResponseCode string `xml:"ResponseCode" json:"ResponseCode"` + AgentID string `xml:"AgentID" json:"AgentID"` + SelectedItems *SelectItems `xml:"SelectedItems" json:"SelectedItems"` } type EventTemplateCardMenuEvent struct { contract.EventInterface models.CallbackMessageHeader - // EventKey string `xml:"EventKey"` - TaskID string `xml:"TaskId"` - CardType string `xml:"CardType"` - ResponseCode string `xml:"ResponseCode"` - AgentID string `xml:"AgentID"` + // EventKey string `xml:"EventKey" json:"EventKey"` + TaskID string `xml:"TaskId" json:"TaskId"` + CardType string `xml:"CardType" json:"CardType"` + ResponseCode string `xml:"ResponseCode" json:"ResponseCode"` + AgentID string `xml:"AgentID" json:"AgentID"` } type EventKFMsgOrEvent struct { contract.EventInterface models.CallbackMessageHeader - Token string `xml:"Token"` - OpenKfID string `xml:"OpenKfId"` + Token string `xml:"Token" json:"Token"` + OpenKfID string `xml:"OpenKfId" json:"OpenKfId"` }