Procházet zdrojové kódy

企业微信新增接口:素材管理、企业群发 (#620)

* 企业微信-客户联系-统计管理

* 企业微信-客户联系-统计管理

* 企业微信-客户联系-统计管理

* debug

* rollback

* debug

* debug

* 获取用户信息

* token

* json.Marshal错误输出

* debug

* bugfix

* 企业微信-通讯录管理相关接口

* 企业微信-通讯录管理

* 企业微信-通讯录管理

* 企业微信-通讯录管理

* 企业微信-[联系我]方式新增和查询

* 企业微信-[联系我]方式新增和获取

* 企业微信-[联系我]方式更新

* 企业微信-[联系我]方式列表、删除

* json.Marshal错误输出

* 已实现接口bug修改

* 历史接口bugfix

* 历史接口bugfix

* comment

* 企业微信:客户联系-消息推送;素材管理-上传图片

* fix

Co-authored-by: wang.yu <wangyu@uniondrug.com>
markwang před 3 roky
rodič
revize
a03f3f9f32
5 změnil soubory, kde provedl 302 přidání a 12 odebrání
  1. 21 12
      doc/api/work.md
  2. 219 0
      work/externalcontact/msg.go
  3. 17 0
      work/material/client.go
  4. 39 0
      work/material/media.go
  5. 6 0
      work/work.go

+ 21 - 12
doc/api/work.md

@@ -62,16 +62,20 @@ host: https://qyapi.weixin.qq.com/
 ### 客户联系
 [官方文档](https://developer.work.weixin.qq.com/document/path/92132/92133/92228)
 
-|       名称        | 请求方式  | URL                                     | 是否已实现   | 使用方法                            | 贡献者      |
-|:---------------:| -------- | :---------------------------------------| ---------- | -------------------------------   |----------|
-|  获取「联系客户统计」数据   | POST     | /cgi-bin/externalcontact/get_user_behavior_data           | YES        | (r *Client) GetUserBehaviorData      | MARKWANG |
-| 获取「群聊数据统计」数据 (按群主聚合的方式) | POST      |  /cgi-bin/externalcontact/groupchat/statistic      | YES        | (r *Client) GetGroupChatStat  | MARKWANG  |
+|            名称            | 请求方式  | URL                                     | 是否已实现   | 使用方法                            | 贡献者      |
+|:------------------------:| -------- | :---------------------------------------| ---------- | -------------------------------   |----------|
+|       获取「联系客户统计」数据       | POST     | /cgi-bin/externalcontact/get_user_behavior_data           | YES        | (r *Client) GetUserBehaviorData      | MARKWANG |
+| 获取「群聊数据统计」数据 (按群主聚合的方式)  | POST      |  /cgi-bin/externalcontact/groupchat/statistic      | YES        | (r *Client) GetGroupChatStat  | MARKWANG  |
 | 获取「群聊数据统计」数据 (按自然日聚合的方式) | POST      |  /cgi-bin/externalcontact/groupchat/statistic_group_by_day      | YES        | (r *Client) GetGroupChatStatByDay  | MARKWANG  |
-| 配置客户联系「联系我」方式 | POST      |  /cgi-bin/externalcontact/add_contact_way      | YES        | (r *Client) AddContactWay  | MARKWANG  |
-| 获取企业已配置的「联系我」方式 | POST      |  /cgi-bin/externalcontact/get_contact_way      | YES        | (r *Client) GetContactWay  | MARKWANG  |
-| 更新企业已配置的「联系我」方式 | POST      |  /cgi-bin/externalcontact/update_contact_way      | YES        | (r *Client) UpdateContactWay  | MARKWANG  |
-| 获取企业已配置的「联系我」列表 | POST      |  /cgi-bin/externalcontact/list_contact_way      | YES        | (r *Client) ListContactWay  | MARKWANG  |
-| 删除企业已配置的「联系我」方式 | POST      |  /cgi-bin/externalcontact/del_contact_way      | YES        | (r *Client) DelContactWay  | MARKWANG  |
+|      配置客户联系「联系我」方式       | POST      |  /cgi-bin/externalcontact/add_contact_way      | YES        | (r *Client) AddContactWay  | MARKWANG  |
+|     获取企业已配置的「联系我」方式      | POST      |  /cgi-bin/externalcontact/get_contact_way      | YES        | (r *Client) GetContactWay  | MARKWANG  |
+|     更新企业已配置的「联系我」方式      | POST      |  /cgi-bin/externalcontact/update_contact_way      | YES        | (r *Client) UpdateContactWay  | MARKWANG  |
+|     获取企业已配置的「联系我」列表      | POST      |  /cgi-bin/externalcontact/list_contact_way      | YES        | (r *Client) ListContactWay  | MARKWANG  |
+|     删除企业已配置的「联系我」方式      | POST      |  /cgi-bin/externalcontact/del_contact_way      | YES        | (r *Client) DelContactWay  | MARKWANG  |
+|          创建企业群发          | POST      |  /cgi-bin/externalcontact/add_msg_template      | YES        | (r *Client) AddMsgTemplate  | MARKWANG  |
+|          获取群发成员发送任务列表          | POST      |  /cgi-bin/externalcontact/get_groupmsg_task      | YES        | (r *Client) GetGroupMsgTask  | MARKWANG  |
+|          获取企业群发成员执行结果          | POST      |  /cgi-bin/externalcontact/get_groupmsg_send_result      | YES        | (r *Client) GetGroupMsgSendResult  | MARKWANG  |
+|          发送新客户欢迎语          | POST      |  /cgi-bin/externalcontact/send_welcome_msg      | YES        | (r *Client) SendWelcomeMsg  | MARKWANG  |
 
 ## 通讯录管理
 [官方文档](https://developer.work.weixin.qq.com/document/path/90193)
@@ -82,7 +86,14 @@ host: https://qyapi.weixin.qq.com/
 |:---------:|------|:----------------------------------------| ---------- | -------------------------------   |----------|
 | 获取子部门ID列表 | GET  | /cgi-bin/department/simplelist          | YES        | (r *Client) DepartmentSimpleList| MARKWANG |
 |  获取部门成员   | GET | /cgi-bin/user/simplelist                | YES        | (r *Client) UserSimpleList  | MARKWANG  |
-=======
+
+
+## 素材管理
+[官方文档](https://developer.work.weixin.qq.com/document/path/91054)
+
+|    名称     | 请求方式 | URL                                     | 是否已实现   | 使用方法                            | 贡献者      |
+|:---------:|------|:----------------------------------------| ---------- | -------------------------------   |----------|
+| 上传图片 | POST  | /cgi-bin/media/uploadimg          | YES        | (r *Client) UploadImg| MARKWANG |
 
 ### 成员管理
 
@@ -91,7 +102,6 @@ host: https://qyapi.weixin.qq.com/
 | 读取成员 | GET      | /cgi-bin/user/get | YES        | (r *Client) UserGet | chcthink |
 
 
-
 ## 群机器人
 
 [官方文档](https://developer.work.weixin.qq.com/document/path/91770)
@@ -101,5 +111,4 @@ host: https://qyapi.weixin.qq.com/
 | 群机器人发送消息 | POST     | /cgi-bin/webhook/send | YES        | (r *Client) RobotBroadcast | chcthink |
 
 ## 应用管理
-
 TODO

+ 219 - 0
work/externalcontact/msg.go

@@ -0,0 +1,219 @@
+package externalcontact
+
+import (
+	"fmt"
+
+	"github.com/silenceper/wechat/v2/util"
+)
+
+const (
+	// AddMsgTemplateURL 创建企业群发
+	AddMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
+	// GetGroupMsgTaskURL 获取群发成员发送任务列表
+	GetGroupMsgTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_task?access_token=%s"
+	// GetGroupMsgSendResultURL 获取企业群发成员执行结果
+	GetGroupMsgSendResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_send_result?access_token=%s"
+	// SendWelcomeMsgURL 发送新客户欢迎语
+	SendWelcomeMsgURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=%s"
+)
+
+// AddMsgTemplateRequest 创建企业群发请求
+type AddMsgTemplateRequest struct {
+	ChatType       string        `json:"chat_type"`
+	ExternalUserID []string      `json:"external_userid"`
+	Sender         string        `json:"sender,omitempty"`
+	Text           MsgText       `json:"text"`
+	Attachments    []*Attachment `json:"attachments"`
+}
+
+// MsgText 文本消息
+type MsgText struct {
+	Content string `json:"content"`
+}
+
+type (
+	// Attachment 附件
+	Attachment struct {
+		MsgType     string                `json:"msgtype"`
+		Image       AttachmentImg         `json:"image,omitempty"`
+		Link        AttachmentLink        `json:"link,omitempty"`
+		MiniProgram AttachmentMiniProgram `json:"miniprogram,omitempty"`
+		Video       AttachmentVideo       `json:"video,omitempty"`
+		File        AttachmentFile        `json:"file,omitempty"`
+	}
+	// AttachmentImg 图片消息
+	AttachmentImg struct {
+		MediaID string `json:"media_id"`
+		PicURL  string `json:"pic_url"`
+	}
+	// AttachmentLink 图文消息
+	AttachmentLink struct {
+		Title  string `json:"title"`
+		PicURL string `json:"picurl"`
+		Desc   string `json:"desc"`
+		URL    string `json:"url"`
+	}
+	// AttachmentMiniProgram 小程序消息
+	AttachmentMiniProgram struct {
+		Title      string `json:"title"`
+		PicMediaID string `json:"pic_media_id"`
+		AppID      string `json:"appid"`
+		Page       string `json:"page"`
+	}
+	// AttachmentVideo 视频消息
+	AttachmentVideo struct {
+		MediaID string `json:"media_id"`
+	}
+	// AttachmentFile 文件消息
+	AttachmentFile struct {
+		MediaID string `json:"media_id"`
+	}
+)
+
+// AddMsgTemplateResponse 创建企业群发响应
+type AddMsgTemplateResponse struct {
+	util.CommonError
+	FailList []string `json:"fail_list"`
+	MsgID    string   `json:"msgid"`
+}
+
+// AddMsgTemplate 创建企业群发
+// see https://developer.work.weixin.qq.com/document/path/92135
+func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResponse, error) {
+	var (
+		accessToken string
+		err         error
+	)
+	if accessToken, err = r.GetAccessToken(); err != nil {
+		return nil, err
+	}
+	var response []byte
+	if response, err = util.PostJSON(fmt.Sprintf(AddMsgTemplateURL, accessToken), req); err != nil {
+		return nil, err
+	}
+	result := &AddMsgTemplateResponse{}
+	if err = util.DecodeWithError(response, result, "AddMsgTemplate"); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// GetGroupMsgTaskRequest 获取群发成员发送任务列表请求
+type GetGroupMsgTaskRequest struct {
+	MsgID  string `json:"msgid"`
+	Limit  int    `json:"limit"`
+	Cursor string `json:"cursor"`
+}
+
+// GetGroupMsgTaskResponse 获取群发成员发送任务列表响应
+type GetGroupMsgTaskResponse struct {
+	util.CommonError
+	NextCursor string  `json:"next_cursor"`
+	TaskList   []*Task `json:"task_list"`
+}
+
+// Task 获取群发成员发送任务列表任务
+type Task struct {
+	UserID   string `json:"userid"`
+	Status   int    `json:"status"`
+	SendTime int    `json:"send_time"`
+}
+
+// GetGroupMsgTask 获取群发成员发送任务列表
+// see https://developer.work.weixin.qq.com/document/path/93338
+func (r *Client) GetGroupMsgTask(req *GetGroupMsgTaskRequest) (*GetGroupMsgTaskResponse, error) {
+	var (
+		accessToken string
+		err         error
+	)
+	if accessToken, err = r.GetAccessToken(); err != nil {
+		return nil, err
+	}
+	var response []byte
+	if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgTaskURL, accessToken), req); err != nil {
+		return nil, err
+	}
+	result := &GetGroupMsgTaskResponse{}
+	if err = util.DecodeWithError(response, result, "GetGroupMsgTask"); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// GetGroupMsgSendResultRequest 获取企业群发成员执行结果请求
+type GetGroupMsgSendResultRequest struct {
+	MsgID  string `json:"msgid"`
+	UserID string `json:"userid"`
+	Limit  int    `json:"limit"`
+	Cursor string `json:"cursor"`
+}
+
+// GetGroupMsgSendResultResponse 获取企业群发成员执行结果响应
+type GetGroupMsgSendResultResponse struct {
+	util.CommonError
+	NextCursor string  `json:"next_cursor"`
+	SendList   []*Send `json:"send_list"`
+}
+
+// Send 企业群发成员执行结果
+type Send struct {
+	ExternalUserID string `json:"external_userid"`
+	ChatID         string `json:"chat_id"`
+	UserID         string `json:"userid"`
+	Status         int    `json:"status"`
+	SendTime       int    `json:"send_time"`
+}
+
+// GetGroupMsgSendResult 获取企业群发成员执行结果
+// see https://developer.work.weixin.qq.com/document/path/93338
+func (r *Client) GetGroupMsgSendResult(req *GetGroupMsgSendResultRequest) (*GetGroupMsgSendResultResponse, error) {
+	var (
+		accessToken string
+		err         error
+	)
+	if accessToken, err = r.GetAccessToken(); err != nil {
+		return nil, err
+	}
+	var response []byte
+	if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgSendResultURL, accessToken), req); err != nil {
+		return nil, err
+	}
+	result := &GetGroupMsgSendResultResponse{}
+	if err = util.DecodeWithError(response, result, "GetGroupMsgSendResult"); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// SendWelcomeMsgRequest 发送新客户欢迎语请求
+type SendWelcomeMsgRequest struct {
+	WelcomeCode string        `json:"welcome_code"`
+	Text        MsgText       `json:"text"`
+	Attachments []*Attachment `json:"attachments"`
+}
+
+// SendWelcomeMsgResponse 发送新客户欢迎语响应
+type SendWelcomeMsgResponse struct {
+	util.CommonError
+}
+
+// SendWelcomeMsg 发送新客户欢迎语
+// see https://developer.work.weixin.qq.com/document/path/92137
+func (r *Client) SendWelcomeMsg(req *SendWelcomeMsgRequest) error {
+	var (
+		accessToken string
+		err         error
+	)
+	if accessToken, err = r.GetAccessToken(); err != nil {
+		return err
+	}
+	var response []byte
+	if response, err = util.PostJSON(fmt.Sprintf(SendWelcomeMsgURL, accessToken), req); err != nil {
+		return err
+	}
+	result := &SendWelcomeMsgResponse{}
+	if err = util.DecodeWithError(response, result, "SendWelcomeMsg"); err != nil {
+		return err
+	}
+	return nil
+}

+ 17 - 0
work/material/client.go

@@ -0,0 +1,17 @@
+package material
+
+import (
+	"github.com/silenceper/wechat/v2/work/context"
+)
+
+// Client 素材管理接口实例
+type Client struct {
+	*context.Context
+}
+
+// NewClient 初始化实例
+func NewClient(ctx *context.Context) *Client {
+	return &Client{
+		ctx,
+	}
+}

+ 39 - 0
work/material/media.go

@@ -0,0 +1,39 @@
+package material
+
+import (
+	"fmt"
+
+	"github.com/silenceper/wechat/v2/util"
+)
+
+const (
+	// UploadImgURL 上传图片
+	UploadImgURL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s"
+)
+
+// UploadImgResponse 上传图片响应
+type UploadImgResponse struct {
+	util.CommonError
+	URL string `json:"url"`
+}
+
+// UploadImg 上传图片
+// @see https://developer.work.weixin.qq.com/document/path/90256
+func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
+	var (
+		accessToken string
+		err         error
+	)
+	if accessToken, err = r.GetAccessToken(); err != nil {
+		return nil, err
+	}
+	var response []byte
+	if response, err = util.PostFile("media", filename, fmt.Sprintf(UploadImgURL, accessToken)); err != nil {
+		return nil, err
+	}
+	result := &UploadImgResponse{}
+	if err = util.DecodeWithError(response, result, "UploadImg"); err != nil {
+		return nil, err
+	}
+	return result, nil
+}

+ 6 - 0
work/work.go

@@ -7,6 +7,7 @@ import (
 	"github.com/silenceper/wechat/v2/work/context"
 	"github.com/silenceper/wechat/v2/work/externalcontact"
 	"github.com/silenceper/wechat/v2/work/kf"
+	"github.com/silenceper/wechat/v2/work/material"
 	"github.com/silenceper/wechat/v2/work/msgaudit"
 	"github.com/silenceper/wechat/v2/work/oauth"
 	"github.com/silenceper/wechat/v2/work/robot"
@@ -57,6 +58,11 @@ func (wk *Work) GetAddressList() *addresslist.Client {
 	return addresslist.NewClient(wk.ctx)
 }
 
+// GetMaterial get material
+func (wk *Work) GetMaterial() *material.Client {
+	return material.NewClient(wk.ctx)
+}
+
 // GetRobot get robot
 func (wk *Work) GetRobot() *robot.Client {
 	return robot.NewClient(wk.ctx)