mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-09 07:02:27 +08:00
企业微信新增接口:素材管理、企业群发 (#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>
This commit is contained in:
@@ -62,16 +62,20 @@ host: https://qyapi.weixin.qq.com/
|
|||||||
### 客户联系
|
### 客户联系
|
||||||
[官方文档](https://developer.work.weixin.qq.com/document/path/92132/92133/92228)
|
[官方文档](https://developer.work.weixin.qq.com/document/path/92132/92133/92228)
|
||||||
|
|
||||||
| 名称 | 请求方式 | URL | 是否已实现 | 使用方法 | 贡献者 |
|
| 名称 | 请求方式 | URL | 是否已实现 | 使用方法 | 贡献者 |
|
||||||
|:---------------:| -------- | :---------------------------------------| ---------- | ------------------------------- |----------|
|
|:------------------------:| -------- | :---------------------------------------| ---------- | ------------------------------- |----------|
|
||||||
| 获取「联系客户统计」数据 | POST | /cgi-bin/externalcontact/get_user_behavior_data | YES | (r *Client) GetUserBehaviorData | MARKWANG |
|
| 获取「联系客户统计」数据 | 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 | YES | (r *Client) GetGroupChatStat | MARKWANG |
|
||||||
| 获取「群聊数据统计」数据 (按自然日聚合的方式) | POST | /cgi-bin/externalcontact/groupchat/statistic_group_by_day | YES | (r *Client) GetGroupChatStatByDay | 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/add_contact_way | YES | (r *Client) AddContactWay | MARKWANG |
|
||||||
| 获取企业已配置的「联系我」方式 | POST | /cgi-bin/externalcontact/get_contact_way | YES | (r *Client) GetContactWay | 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/update_contact_way | YES | (r *Client) UpdateContactWay | MARKWANG |
|
||||||
| 获取企业已配置的「联系我」列表 | POST | /cgi-bin/externalcontact/list_contact_way | YES | (r *Client) ListContactWay | 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/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)
|
[官方文档](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 |
|
| 获取子部门ID列表 | GET | /cgi-bin/department/simplelist | YES | (r *Client) DepartmentSimpleList| MARKWANG |
|
||||||
| 获取部门成员 | GET | /cgi-bin/user/simplelist | YES | (r *Client) UserSimpleList | 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 |
|
| 读取成员 | GET | /cgi-bin/user/get | YES | (r *Client) UserGet | chcthink |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 群机器人
|
## 群机器人
|
||||||
|
|
||||||
[官方文档](https://developer.work.weixin.qq.com/document/path/91770)
|
[官方文档](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 |
|
| 群机器人发送消息 | POST | /cgi-bin/webhook/send | YES | (r *Client) RobotBroadcast | chcthink |
|
||||||
|
|
||||||
## 应用管理
|
## 应用管理
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
219
work/externalcontact/msg.go
Normal file
219
work/externalcontact/msg.go
Normal file
@@ -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
work/material/client.go
Normal file
17
work/material/client.go
Normal file
@@ -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
work/material/media.go
Normal file
39
work/material/media.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/silenceper/wechat/v2/work/context"
|
"github.com/silenceper/wechat/v2/work/context"
|
||||||
"github.com/silenceper/wechat/v2/work/externalcontact"
|
"github.com/silenceper/wechat/v2/work/externalcontact"
|
||||||
"github.com/silenceper/wechat/v2/work/kf"
|
"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/msgaudit"
|
||||||
"github.com/silenceper/wechat/v2/work/oauth"
|
"github.com/silenceper/wechat/v2/work/oauth"
|
||||||
"github.com/silenceper/wechat/v2/work/robot"
|
"github.com/silenceper/wechat/v2/work/robot"
|
||||||
@@ -57,6 +58,11 @@ func (wk *Work) GetAddressList() *addresslist.Client {
|
|||||||
return addresslist.NewClient(wk.ctx)
|
return addresslist.NewClient(wk.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMaterial get material
|
||||||
|
func (wk *Work) GetMaterial() *material.Client {
|
||||||
|
return material.NewClient(wk.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// GetRobot get robot
|
// GetRobot get robot
|
||||||
func (wk *Work) GetRobot() *robot.Client {
|
func (wk *Work) GetRobot() *robot.Client {
|
||||||
return robot.NewClient(wk.ctx)
|
return robot.NewClient(wk.ctx)
|
||||||
|
|||||||
Reference in New Issue
Block a user