From 2080aaf50784d917dc7e820bea963d93e2d5ddce Mon Sep 17 00:00:00 2001 From: bozhang75 Date: Fri, 29 Jul 2022 16:05:31 +0800 Subject: [PATCH] add webhook --- wechat_sdk.go | 24 +-- work/webhook/webhook.go | 355 ++++++++++++++++++++++++++++++++++++++++ work_sdk.go | 6 + 3 files changed, 373 insertions(+), 12 deletions(-) diff --git a/wechat_sdk.go b/wechat_sdk.go index be602e4..957ae6d 100644 --- a/wechat_sdk.go +++ b/wechat_sdk.go @@ -26,16 +26,16 @@ type Wechat struct { //用户wechat配置 type Config struct { - AppID string //开发者ID(AppID) - AppSecret string //开发者PWD AppSecret - Token string //令牌(Token) - EncodingAESKey string //消息加解密密钥 EncodingAESKey - PayMchId string //支付 - 商户 ID - PayNotifyUrl string //支付 - 接受微信支付结果通知的接口地址 - PayKey string //支付 - 商户后台设置的支付 key - Cache cache.Cache //缓存 - ThirdAccessToken bool //是否共享其它accessToken,非appID获取 默认false - ProxyUrl string //缓存配置文件 + AppID string //开发者ID(AppID) + AppSecret string //开发者PWD AppSecret + Token string //令牌(Token) + EncodingAESKey string //消息加解密密钥 EncodingAESKey + PayMchId string //支付 - 商户 ID + PayNotifyUrl string //支付 - 接受微信支付结果通知的接口地址 + PayKey string //支付 - 商户后台设置的支付 key + Cache cache.Cache //缓存 + ThirdAccessToken bool //是否共享其它accessToken,非appID获取 默认false + ProxyUrl string //缓存配置文件 } //实例化wechat @@ -77,7 +77,7 @@ func (wc *Wechat) GetResponseServer(req *http.Request) *server.Server { func (wc *Wechat) GetAccessToken() string { accessToken, err := wc.Context.GetAccessToken() if err != nil { - fmt.Printf("mp GetAccessToken Err:%+v",err) + fmt.Printf("mp GetAccessToken Err:%+v", err) } return accessToken } @@ -129,4 +129,4 @@ func (wc *Wechat) GetAccount() *account.Account { //账户管理 func (wc *Wechat) GetJSSDK() *jssdk.JSAPISDK { return jssdk.NewJSSDK(wc.Context) -} \ No newline at end of file +} diff --git a/work/webhook/webhook.go b/work/webhook/webhook.go index cf6f5e0..655bbf4 100644 --- a/work/webhook/webhook.go +++ b/work/webhook/webhook.go @@ -6,3 +6,358 @@ */ package webhook + +import ( + "encoding/json" + "fmt" + "github.com/yijizhichang/wechat-sdk/util" + "github.com/yijizhichang/wechat-sdk/work/core" +) + +const ( + WebhookUploadMediaURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=%s&type=%s" +) + +//webhook消息类型 +type WebhookMsgType string +type WebhookCardType string + +const ( + // webhook消息类型 + WebhookMsgTypeText WebhookMsgType = "text" // 文本消息 + WebhookMsgTypeMarkdown = "markdown" // markdown消息 + WebhookMsgTypeImage = "image" // 图片消息 + WebhookMsgTypeNews = "news" // 图文消息 + WebhookMsgTypeFile = "file" // 文件消息 + WebhookMsgTypeTemplateCard = "template_card" // 模板卡片消息 +) + +const ( + //卡版类型 + WebhookCardTypeText WebhookCardType = "text_notice" //文本卡片 + WebhookCardTypeNews = "news_notice" //图文卡片 +) + +//Webhook 机器人消息 +type Webhook struct { + *core.Context +} + +//NewWebhook 实例化 +func NewWebhook(context *core.Context) *Webhook { + m := new(Webhook) + m.Context = context + return m +} + +//发送文本消息 +type SendTextWebhookReq struct { + Msgtype string `json:"msgtype"` + Text struct { + Content string `json:"content"` + MentionedList []string `json:"mentioned_list"` + MentionedMobileList []string `json:"mentioned_mobile_list"` + } `json:"text"` +} + +func (m *Webhook) SendTextMessage(webhook string, req SendTextWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendTextMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送markdown类型消息 +type SendMarkdownWebhookReq struct { + Msgtype string `json:"msgtype"` + Markdown struct { + Content string `json:"content"` + } `json:"markdown"` +} + +func (m *Webhook) SendMarkdownMessage(webhook string, req SendMarkdownWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendMarkdownMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送图片类型 +type SendImageWebhookReq struct { + Msgtype string `json:"msgtype"` + Image struct { + Base64 string `json:"base64"` + Md5 string `json:"md5"` + } `json:"image"` +} + +func (m *Webhook) SendImageMessage(webhook string, req SendImageWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendImageMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送图文类型 +type SendNewsWebhookReq struct { + Msgtype string `json:"msgtype"` + News struct { + Articles []ArticlesItem `json:"articles"` + } `json:"news"` +} + +type ArticlesItem struct { + Title string `json:"title"` + Description string `json:"description"` + Url string `json:"url"` + Picurl string `json:"picurl"` +} + +func (m *Webhook) SendNewsMessage(webhook string, req SendNewsWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendNewsMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送文件类型 +type SendFileWebhookReq struct { + Msgtype string `json:"msgtype"` + File struct { + MediaId string `json:"media_id"` + } `json:"file"` +} + +func (m *Webhook) SendFileMessage(webhook string, req SendFileWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendFileMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送模板卡片 文本通知 +type SendTemplateCardTextWebhookReq struct { + Msgtype string `json:"msgtype"` + TemplateCard struct { + CardType string `json:"card_type"` + Source struct { + IconUrl string `json:"icon_url"` + Desc string `json:"desc"` + DescColor int `json:"desc_color"` + } `json:"source"` + MainTitle struct { + Title string `json:"title"` + Desc string `json:"desc"` + } `json:"main_title"` + EmphasisContent struct { + Title string `json:"title"` + Desc string `json:"desc"` + } `json:"emphasis_content"` + QuoteArea struct { + Type int `json:"type"` + Url string `json:"url"` + Appid string `json:"appid"` + Pagepath string `json:"pagepath"` + Title string `json:"title"` + QuoteText string `json:"quote_text"` + } `json:"quote_area"` + SubTitleText string `json:"sub_title_text"` + HorizontalContentList []struct { + Keyname string `json:"keyname"` + Value string `json:"value"` + Type int `json:"type,omitempty"` + Url string `json:"url,omitempty"` + MediaId string `json:"media_id,omitempty"` + } `json:"horizontal_content_list"` + JumpList []struct { + Type int `json:"type"` + Url string `json:"url,omitempty"` + Title string `json:"title"` + Appid string `json:"appid,omitempty"` + Pagepath string `json:"pagepath,omitempty"` + } `json:"jump_list"` + CardAction struct { + Type int `json:"type"` + Url string `json:"url"` + Appid string `json:"appid"` + Pagepath string `json:"pagepath"` + } `json:"card_action"` + } `json:"template_card"` +} + +func (m *Webhook) SendTemplateCardTextMessage(webhook string, req SendTemplateCardTextWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendTemplateCardTextMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//发送模板卡片 图文通知 +type SendTemplateCardNewsWebhookReq struct { + Msgtype string `json:"msgtype"` + TemplateCard struct { + CardType string `json:"card_type"` + Source struct { + IconUrl string `json:"icon_url"` + Desc string `json:"desc"` + DescColor int `json:"desc_color"` + } `json:"source"` + MainTitle struct { + Title string `json:"title"` + Desc string `json:"desc"` + } `json:"main_title"` + CardImage struct { + Url string `json:"url"` + AspectRatio float64 `json:"aspect_ratio"` + } `json:"card_image"` + ImageTextArea struct { + Type int `json:"type"` + Url string `json:"url"` + Title string `json:"title"` + Desc string `json:"desc"` + ImageUrl string `json:"image_url"` + } `json:"image_text_area"` + QuoteArea struct { + Type int `json:"type"` + Url string `json:"url"` + Appid string `json:"appid"` + Pagepath string `json:"pagepath"` + Title string `json:"title"` + QuoteText string `json:"quote_text"` + } `json:"quote_area"` + VerticalContentList []struct { + Title string `json:"title"` + Desc string `json:"desc"` + } `json:"vertical_content_list"` + HorizontalContentList []struct { + Keyname string `json:"keyname"` + Value string `json:"value"` + Type int `json:"type,omitempty"` + Url string `json:"url,omitempty"` + MediaId string `json:"media_id,omitempty"` + } `json:"horizontal_content_list"` + JumpList []struct { + Type int `json:"type"` + Url string `json:"url,omitempty"` + Title string `json:"title"` + Appid string `json:"appid,omitempty"` + Pagepath string `json:"pagepath,omitempty"` + } `json:"jump_list"` + CardAction struct { + Type int `json:"type"` + Url string `json:"url"` + Appid string `json:"appid"` + Pagepath string `json:"pagepath"` + } `json:"card_action"` + } `json:"template_card"` +} + +func (m *Webhook) SendTemplateCardNewsMessage(webhook string, req SendTemplateCardNewsWebhookReq) (result *util.WxError, err error) { + + response, err := util.PostJSON(webhook, req, m.ProxyUrl) + + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("SendTemplateCardNewsMessage error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} + +//上传文件 +type UploadWebhookMediaReq struct { + util.WxError + Type string `json:"type"` + MediaId string `json:"media_id"` + CreatedAt string `json:"created_at"` +} + +func (m *Webhook) UploadQyTempMedia(webhookKey, fileType, filename string) (result *UploadWebhookMediaReq, err error) { + qyUrl := fmt.Sprintf(WebhookUploadMediaURL, webhookKey, fileType) + + response, err := util.PostFile("media", filename, qyUrl, m.ProxyUrl) + if err != nil { + return + } + + err = json.Unmarshal(response, &result) + if err != nil { + return + } + if result.ErrCode != 0 { + err = fmt.Errorf("UploadQyTempMedia error : errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg) + } + return +} diff --git a/work_sdk.go b/work_sdk.go index 4df24ec..ecd7388 100644 --- a/work_sdk.go +++ b/work_sdk.go @@ -13,6 +13,7 @@ import ( "github.com/yijizhichang/wechat-sdk/work/oauth2" "github.com/yijizhichang/wechat-sdk/work/server" "github.com/yijizhichang/wechat-sdk/work/tools" + "github.com/yijizhichang/wechat-sdk/work/webhook" "net/http" "sync" ) @@ -235,3 +236,8 @@ func (qw *QyWechat) GetLiving() *tools.Living { func (qw *QyWechat) GetCalendar() *tools.Calendar { return tools.NewCalendar(qw.Context) } + +//机器人管理 +func (qw *QyWechat) GetWebhook() *webhook.Webhook { + return webhook.NewWebhook(qw.Context) +}