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 }