mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-07 22:22:28 +08:00
Merge remote-tracking branch '官方/v2' into release-2.0
# Conflicts: # work/message/client.go # work/message/message.go # work/oauth/oauth.go # work/work.go
This commit is contained in:
@@ -7,11 +7,32 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// DepartmentSimpleListURL 获取子部门ID列表
|
||||
DepartmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
||||
// departmentCreateURL 创建部门
|
||||
departmentCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token=%s"
|
||||
// departmentSimpleListURL 获取子部门ID列表
|
||||
departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
||||
// departmentListURL 获取部门列表
|
||||
departmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s"
|
||||
departmentListByIDURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s&id=%d"
|
||||
// departmentGetURL 获取单个部门详情 https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=ACCESS_TOKEN&id=ID
|
||||
departmentGetURL = "https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=%s&id=%d"
|
||||
)
|
||||
|
||||
type (
|
||||
// DepartmentCreateRequest 创建部门数据请求
|
||||
DepartmentCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
NameEn string `json:"name_en,omitempty"`
|
||||
ParentID int `json:"parentid"`
|
||||
Order int `json:"order,omitempty"`
|
||||
ID int `json:"id,omitempty"`
|
||||
}
|
||||
// DepartmentCreateResponse 创建部门数据响应
|
||||
DepartmentCreateResponse struct {
|
||||
util.CommonError
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
// DepartmentSimpleListResponse 获取子部门ID列表响应
|
||||
DepartmentSimpleListResponse struct {
|
||||
util.CommonError
|
||||
@@ -23,8 +44,47 @@ type (
|
||||
ParentID int `json:"parentid"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// DepartmentListResponse 获取部门列表响应
|
||||
DepartmentListResponse struct {
|
||||
util.CommonError
|
||||
Department []*Department `json:"department"`
|
||||
}
|
||||
// Department 部门列表数据
|
||||
Department struct {
|
||||
ID int `json:"id"` // 创建的部门id
|
||||
Name string `json:"name"` // 部门名称
|
||||
NameEn string `json:"name_en"` // 英文名称
|
||||
DepartmentLeader []string `json:"department_leader"` // 部门负责人的UserID
|
||||
ParentID int `json:"parentid"` // 父部门id。根部门为1
|
||||
Order int `json:"order"` // 在父部门中的次序值。order值大的排序靠前
|
||||
}
|
||||
// DepartmentGetResponse 获取单个部门详情
|
||||
DepartmentGetResponse struct {
|
||||
util.CommonError
|
||||
Department Department `json:"department"`
|
||||
}
|
||||
)
|
||||
|
||||
// DepartmentCreate 创建部门
|
||||
// see https://developer.work.weixin.qq.com/document/path/90205
|
||||
func (r *Client) DepartmentCreate(req *DepartmentCreateRequest) (*DepartmentCreateResponse, 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(departmentCreateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DepartmentCreateResponse{}
|
||||
err = util.DecodeWithError(response, result, "DepartmentCreate")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// DepartmentSimpleList 获取子部门ID列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/95350
|
||||
func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error) {
|
||||
@@ -36,12 +96,67 @@ func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error)
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(DepartmentSimpleListURL, accessToken, departmentID)); err != nil {
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(departmentSimpleListURL, accessToken, departmentID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DepartmentSimpleListResponse{}
|
||||
if err = util.DecodeWithError(response, result, "DepartmentSimpleList"); err != nil {
|
||||
err = util.DecodeWithError(response, result, "DepartmentSimpleList")
|
||||
return result.DepartmentID, err
|
||||
}
|
||||
|
||||
// DepartmentList 获取部门列表
|
||||
// @desc https://developer.work.weixin.qq.com/document/path/90208
|
||||
func (r *Client) DepartmentList() ([]*Department, error) {
|
||||
return r.DepartmentListByID(0)
|
||||
}
|
||||
|
||||
// DepartmentListByID 获取部门列表
|
||||
//
|
||||
// departmentID 部门id。获取指定部门及其下的子部门(以及子部门的子部门等等,递归)
|
||||
//
|
||||
// @desc https://developer.work.weixin.qq.com/document/path/90208
|
||||
func (r *Client) DepartmentListByID(departmentID int) ([]*Department, error) {
|
||||
var formatURL string
|
||||
|
||||
// 获取accessToken
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.DepartmentID, nil
|
||||
|
||||
if departmentID > 0 {
|
||||
formatURL = fmt.Sprintf(departmentListByIDURL, accessToken, departmentID)
|
||||
} else {
|
||||
formatURL = fmt.Sprintf(departmentListURL, accessToken)
|
||||
}
|
||||
|
||||
// 发起http请求
|
||||
response, err := util.HTTPGet(formatURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 按照结构体解析返回值
|
||||
result := &DepartmentListResponse{}
|
||||
err = util.DecodeWithError(response, result, "DepartmentList")
|
||||
// 返回数据
|
||||
return result.Department, err
|
||||
}
|
||||
|
||||
// DepartmentGet 获取单个部门详情
|
||||
// see https://developer.work.weixin.qq.com/document/path/95351
|
||||
func (r *Client) DepartmentGet(departmentID int) (*Department, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(departmentGetURL, accessToken, departmentID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DepartmentGetResponse{}
|
||||
err = util.DecodeWithError(response, result, "DepartmentGet")
|
||||
return &result.Department, err
|
||||
}
|
||||
|
||||
220
work/addresslist/linkedcorp.go
Normal file
220
work/addresslist/linkedcorp.go
Normal file
@@ -0,0 +1,220 @@
|
||||
package addresslist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// getPermListURL 获取应用的可见范围
|
||||
getPermListURL = "https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/agent/get_perm_list?access_token=%s"
|
||||
// getLinkedCorpUserURL 获取互联企业成员详细信息
|
||||
getLinkedCorpUserURL = "https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/user/get?access_token=%s"
|
||||
// linkedCorpSimpleListURL 获取互联企业部门成员
|
||||
linkedCorpSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/user/simplelist?access_token=%s"
|
||||
// linkedCorpUserListURL 获取互联企业部门成员详情
|
||||
linkedCorpUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/user/list?access_token=%s"
|
||||
// linkedCorpDepartmentListURL 获取互联企业部门列表
|
||||
linkedCorpDepartmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/department/list?access_token=%s"
|
||||
)
|
||||
|
||||
// GetPermListResponse 获取应用的可见范围响应
|
||||
type GetPermListResponse struct {
|
||||
util.CommonError
|
||||
UserIDs []string `json:"userids"`
|
||||
DepartmentIDs []string `json:"department_ids"`
|
||||
}
|
||||
|
||||
// GetPermList 获取应用的可见范围
|
||||
// see https://developer.work.weixin.qq.com/document/path/93172
|
||||
func (r *Client) GetPermList() (*GetPermListResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPPost(fmt.Sprintf(getPermListURL, accessToken), ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetPermListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetPermList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetLinkedCorpUserRequest 获取互联企业成员详细信息请求
|
||||
type GetLinkedCorpUserRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
}
|
||||
|
||||
// GetLinkedCorpUserResponse 获取互联企业成员详细信息响应
|
||||
type GetLinkedCorpUserResponse struct {
|
||||
util.CommonError
|
||||
UserInfo LinkedCorpUserInfo `json:"user_info"`
|
||||
}
|
||||
|
||||
// LinkedCorpUserInfo 互联企业成员详细信息
|
||||
type LinkedCorpUserInfo struct {
|
||||
UserID string `json:"userid"`
|
||||
Name string `json:"name"`
|
||||
Department []string `json:"department"`
|
||||
Mobile string `json:"mobile"`
|
||||
Telephone string `json:"telephone"`
|
||||
Email string `json:"email"`
|
||||
Position string `json:"position"`
|
||||
CorpID string `json:"corpid"`
|
||||
Extattr Extattr `json:"extattr"`
|
||||
}
|
||||
|
||||
// Extattr 互联企业成员详细信息扩展属性
|
||||
type Extattr struct {
|
||||
Attrs []ExtattrItem `json:"attrs"`
|
||||
}
|
||||
|
||||
// ExtattrItem 互联企业成员详细信息扩展属性条目
|
||||
type ExtattrItem struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value,omitempty"`
|
||||
Type int `json:"type"`
|
||||
Text ExtattrItemText `json:"text,omitempty"`
|
||||
Web ExtattrItemWeb `json:"web,omitempty"`
|
||||
}
|
||||
|
||||
// ExtattrItemText 互联企业成员详细信息自定义属性(文本)
|
||||
type ExtattrItemText struct {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// ExtattrItemWeb 互联企业成员详细信息自定义属性(网页)
|
||||
type ExtattrItemWeb struct {
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
// GetLinkedCorpUser 获取互联企业成员详细信息
|
||||
// see https://developer.work.weixin.qq.com/document/path/93171
|
||||
func (r *Client) GetLinkedCorpUser(req *GetLinkedCorpUserRequest) (*GetLinkedCorpUserResponse, 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(getLinkedCorpUserURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetLinkedCorpUserResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetLinkedCorpUser")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// LinkedCorpSimpleListRequest 获取互联企业部门成员请求
|
||||
type LinkedCorpSimpleListRequest struct {
|
||||
DepartmentID string `json:"department_id"`
|
||||
}
|
||||
|
||||
// LinkedCorpSimpleListResponse 获取互联企业部门成员响应
|
||||
type LinkedCorpSimpleListResponse struct {
|
||||
util.CommonError
|
||||
Userlist []LinkedCorpUser `json:"userlist"`
|
||||
}
|
||||
|
||||
// LinkedCorpUser 企业部门成员
|
||||
type LinkedCorpUser struct {
|
||||
UserID string `json:"userid"`
|
||||
Name string `json:"name"`
|
||||
Department []string `json:"department"`
|
||||
CorpID string `json:"corpid"`
|
||||
}
|
||||
|
||||
// LinkedCorpSimpleList 获取互联企业部门成员
|
||||
// see https://developer.work.weixin.qq.com/document/path/93168
|
||||
func (r *Client) LinkedCorpSimpleList(req *LinkedCorpSimpleListRequest) (*LinkedCorpSimpleListResponse, 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(linkedCorpSimpleListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &LinkedCorpSimpleListResponse{}
|
||||
err = util.DecodeWithError(response, result, "LinkedCorpSimpleList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// LinkedCorpUserListRequest 获取互联企业部门成员详情请求
|
||||
type LinkedCorpUserListRequest struct {
|
||||
DepartmentID string `json:"department_id"`
|
||||
}
|
||||
|
||||
// LinkedCorpUserListResponse 获取互联企业部门成员详情响应
|
||||
type LinkedCorpUserListResponse struct {
|
||||
util.CommonError
|
||||
UserList []LinkedCorpUserInfo `json:"userlist"`
|
||||
}
|
||||
|
||||
// LinkedCorpUserList 获取互联企业部门成员详情
|
||||
// see https://developer.work.weixin.qq.com/document/path/93169
|
||||
func (r *Client) LinkedCorpUserList(req *LinkedCorpUserListRequest) (*LinkedCorpUserListResponse, 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(linkedCorpUserListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &LinkedCorpUserListResponse{}
|
||||
err = util.DecodeWithError(response, result, "LinkedCorpUserList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// LinkedCorpDepartmentListRequest 获取互联企业部门列表请求
|
||||
type LinkedCorpDepartmentListRequest struct {
|
||||
DepartmentID string `json:"department_id"`
|
||||
}
|
||||
|
||||
// LinkedCorpDepartmentListResponse 获取互联企业部门列表响应
|
||||
type LinkedCorpDepartmentListResponse struct {
|
||||
util.CommonError
|
||||
DepartmentList []LinkedCorpDepartment `json:"department_list"`
|
||||
}
|
||||
|
||||
// LinkedCorpDepartment 互联企业部门
|
||||
type LinkedCorpDepartment struct {
|
||||
DepartmentID string `json:"department_id"`
|
||||
DepartmentName string `json:"department_name"`
|
||||
ParentID string `json:"parentid"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// LinkedCorpDepartmentList 获取互联企业部门列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93170
|
||||
func (r *Client) LinkedCorpDepartmentList(req *LinkedCorpDepartmentListRequest) (*LinkedCorpDepartmentListResponse, 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(linkedCorpDepartmentListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &LinkedCorpDepartmentListResponse{}
|
||||
err = util.DecodeWithError(response, result, "LinkedCorpDepartmentList")
|
||||
return result, err
|
||||
}
|
||||
232
work/addresslist/tag.go
Normal file
232
work/addresslist/tag.go
Normal file
@@ -0,0 +1,232 @@
|
||||
package addresslist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// createTagURL 创建标签
|
||||
createTagURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/create?access_token=%s"
|
||||
// updateTagURL 更新标签名字
|
||||
updateTagURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/update?access_token=%s"
|
||||
// deleteTagURL 删除标签
|
||||
deleteTagURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/delete?access_token=%s&tagid=%d"
|
||||
// getTagURL 获取标签成员
|
||||
getTagURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?access_token=%s&tagid=%d"
|
||||
// addTagUsersURL 增加标签成员
|
||||
addTagUsersURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers?access_token=%s"
|
||||
// delTagUsersURL 删除标签成员
|
||||
delTagUsersURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers?access_token=%s"
|
||||
// listTagURL 获取标签列表
|
||||
listTagURL = "https://qyapi.weixin.qq.com/cgi-bin/tag/list?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
// CreateTagRequest 创建标签请求
|
||||
CreateTagRequest struct {
|
||||
TagName string `json:"tagname"`
|
||||
TagID int `json:"tagid,omitempty"`
|
||||
}
|
||||
// CreateTagResponse 创建标签响应
|
||||
CreateTagResponse struct {
|
||||
util.CommonError
|
||||
TagID int `json:"tagid"`
|
||||
}
|
||||
)
|
||||
|
||||
// CreateTag 创建标签
|
||||
// see https://developer.work.weixin.qq.com/document/path/90210
|
||||
func (r *Client) CreateTag(req *CreateTagRequest) (*CreateTagResponse, 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(createTagURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CreateTagResponse{}
|
||||
err = util.DecodeWithError(response, result, "CreateTag")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// UpdateTagRequest 更新标签名字请求
|
||||
UpdateTagRequest struct {
|
||||
TagID int `json:"tagid"`
|
||||
TagName string `json:"tagname"`
|
||||
}
|
||||
)
|
||||
|
||||
// UpdateTag 更新标签名字
|
||||
// see https://developer.work.weixin.qq.com/document/path/90211
|
||||
func (r *Client) UpdateTag(req *UpdateTagRequest) 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(updateTagURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateTag")
|
||||
}
|
||||
|
||||
// DeleteTag 删除标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90212
|
||||
func (r *Client) DeleteTag(tagID int) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(deleteTagURL, accessToken, tagID)); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DeleteTag")
|
||||
}
|
||||
|
||||
type (
|
||||
// GetTagResponse 获取标签成员响应
|
||||
GetTagResponse struct {
|
||||
util.CommonError
|
||||
TagName string `json:"tagname"`
|
||||
UserList []GetTagUserList `json:"userlist"`
|
||||
PartyList []int `json:"partylist"`
|
||||
}
|
||||
// GetTagUserList 标签中包含的成员列表
|
||||
GetTagUserList struct {
|
||||
UserID string `json:"userid"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetTag 获取标签成员
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90213
|
||||
func (r *Client) GetTag(tagID int) (*GetTagResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(getTagURL, accessToken, tagID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetTagResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetTag")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// AddTagUsersRequest 增加标签成员请求
|
||||
AddTagUsersRequest struct {
|
||||
TagID int `json:"tagid"`
|
||||
UserList []string `json:"userlist"`
|
||||
PartyList []int `json:"partylist"`
|
||||
}
|
||||
// AddTagUsersResponse 增加标签成员响应
|
||||
AddTagUsersResponse struct {
|
||||
util.CommonError
|
||||
InvalidList string `json:"invalidlist"`
|
||||
InvalidParty []int `json:"invalidparty"`
|
||||
}
|
||||
)
|
||||
|
||||
// AddTagUsers 增加标签成员
|
||||
// see https://developer.work.weixin.qq.com/document/path/90214
|
||||
func (r *Client) AddTagUsers(req *AddTagUsersRequest) (*AddTagUsersResponse, 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(addTagUsersURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddTagUsersResponse{}
|
||||
err = util.DecodeWithError(response, result, "AddTagUsers")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// DelTagUsersRequest 删除标签成员请求
|
||||
DelTagUsersRequest struct {
|
||||
TagID int `json:"tagid"`
|
||||
UserList []string `json:"userlist"`
|
||||
PartyList []int `json:"partylist"`
|
||||
}
|
||||
// DelTagUsersResponse 删除标签成员响应
|
||||
DelTagUsersResponse struct {
|
||||
util.CommonError
|
||||
InvalidList string `json:"invalidlist"`
|
||||
InvalidParty []int `json:"invalidparty"`
|
||||
}
|
||||
)
|
||||
|
||||
// DelTagUsers 删除标签成员
|
||||
// see https://developer.work.weixin.qq.com/document/path/90215
|
||||
func (r *Client) DelTagUsers(req *DelTagUsersRequest) (*DelTagUsersResponse, 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(delTagUsersURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DelTagUsersResponse{}
|
||||
err = util.DecodeWithError(response, result, "DelTagUsers")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// ListTagResponse 获取标签列表响应
|
||||
ListTagResponse struct {
|
||||
util.CommonError
|
||||
TagList []Tag `json:"taglist"`
|
||||
}
|
||||
// Tag 标签
|
||||
Tag struct {
|
||||
TagID int `json:"tagid"`
|
||||
TagName string `json:"tagname"`
|
||||
}
|
||||
)
|
||||
|
||||
// ListTag 获取标签列表
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90216
|
||||
func (r *Client) ListTag() (*ListTagResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(listTagURL, accessToken)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListTagResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListTag")
|
||||
return result, err
|
||||
}
|
||||
@@ -2,17 +2,26 @@ package addresslist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// UserSimpleListURL 获取部门成员
|
||||
UserSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=%s&department_id=%d"
|
||||
// UserGetURL 读取成员
|
||||
UserGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s"
|
||||
// UserListIDURL 获取成员ID列表
|
||||
UserListIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id?access_token=%s"
|
||||
// userSimpleListURL 获取部门成员
|
||||
userSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist"
|
||||
// userCreateURL 创建成员
|
||||
userCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=%s"
|
||||
// userGetURL 读取成员
|
||||
userGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get"
|
||||
// userDeleteURL 删除成员
|
||||
userDeleteURL = "https://qyapi.weixin.qq.com/cgi-bin/user/delete"
|
||||
// userListIDURL 获取成员ID列表
|
||||
userListIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id"
|
||||
// convertToOpenIDURL userID转openID
|
||||
convertToOpenIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid"
|
||||
// convertToUserIDURL openID转userID
|
||||
convertToUserIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_userid"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -41,15 +50,108 @@ func (r *Client) UserSimpleList(departmentID int) ([]*UserList, error) {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(UserSimpleListURL, accessToken, departmentID)); err != nil {
|
||||
if response, err = util.HTTPGet(strings.Join([]string{
|
||||
userSimpleListURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
"department_id": departmentID,
|
||||
}),
|
||||
}, "?")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UserSimpleListResponse{}
|
||||
err = util.DecodeWithError(response, result, "UserSimpleList")
|
||||
if err != nil {
|
||||
return result.UserList, err
|
||||
}
|
||||
|
||||
type (
|
||||
// UserCreateRequest 创建成员数据请求
|
||||
UserCreateRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
Name string `json:"name"`
|
||||
Alias string `json:"alias"`
|
||||
Mobile string `json:"mobile"`
|
||||
Department []int `json:"department"`
|
||||
Order []int `json:"order"`
|
||||
Position string `json:"position"`
|
||||
Gender int `json:"gender"`
|
||||
Email string `json:"email"`
|
||||
BizMail string `json:"biz_mail"`
|
||||
IsLeaderInDept []int `json:"is_leader_in_dept"`
|
||||
DirectLeader []string `json:"direct_leader"`
|
||||
Enable int `json:"enable"`
|
||||
AvatarMediaid string `json:"avatar_mediaid"`
|
||||
Telephone string `json:"telephone"`
|
||||
Address string `json:"address"`
|
||||
MainDepartment int `json:"main_department"`
|
||||
Extattr struct {
|
||||
Attrs []ExtraAttr `json:"attrs"`
|
||||
} `json:"extattr"`
|
||||
ToInvite bool `json:"to_invite"`
|
||||
ExternalPosition string `json:"external_position"`
|
||||
ExternalProfile ExternalProfile `json:"external_profile"`
|
||||
}
|
||||
// ExtraAttr 扩展属性
|
||||
ExtraAttr struct {
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Text struct {
|
||||
Value string `json:"value"`
|
||||
} `json:"text,omitempty"`
|
||||
Web struct {
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
} `json:"web,omitempty"`
|
||||
}
|
||||
// ExternalProfile 成员对外信息
|
||||
ExternalProfile struct {
|
||||
ExternalCorpName string `json:"external_corp_name"`
|
||||
WechatChannels struct {
|
||||
Nickname string `json:"nickname"`
|
||||
Status int `json:"status"`
|
||||
} `json:"wechat_channels"`
|
||||
ExternalAttr []ExternalProfileAttr `json:"external_attr"`
|
||||
}
|
||||
// ExternalProfileAttr 成员对外信息属性
|
||||
ExternalProfileAttr struct {
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Text struct {
|
||||
Value string `json:"value"`
|
||||
} `json:"text,omitempty"`
|
||||
Web struct {
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
} `json:"web,omitempty"`
|
||||
Miniprogram struct {
|
||||
Appid string `json:"appid"`
|
||||
Pagepath string `json:"pagepath"`
|
||||
Title string `json:"title"`
|
||||
} `json:"miniprogram,omitempty"`
|
||||
}
|
||||
// UserCreateResponse 创建成员数据响应
|
||||
UserCreateResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// UserCreate 创建成员
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90195
|
||||
func (r *Client) UserCreate(req *UserCreateRequest) (*UserCreateResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.UserList, nil
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(userCreateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UserCreateResponse{}
|
||||
err = util.DecodeWithError(response, result, "UserCreate")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UserGetResponse 获取部门成员响应
|
||||
@@ -114,7 +216,7 @@ type UserGetResponse struct {
|
||||
} `json:"external_profile"` // 成员对外属性,字段详情见对外属性;代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
||||
}
|
||||
|
||||
// UserGet 获取部门成员
|
||||
// UserGet 读取成员
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90196
|
||||
func (r *Client) UserGet(UserID string) (*UserGetResponse, error) {
|
||||
var (
|
||||
@@ -125,15 +227,52 @@ func (r *Client) UserGet(UserID string) (*UserGetResponse, error) {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(UserGetURL, accessToken, UserID)); err != nil {
|
||||
|
||||
if response, err = util.HTTPGet(
|
||||
strings.Join([]string{
|
||||
userGetURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
"userid": UserID,
|
||||
}),
|
||||
}, "?")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UserGetResponse{}
|
||||
err = util.DecodeWithError(response, result, "UserGet")
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// UserDeleteResponse 删除成员数据响应
|
||||
UserDeleteResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// UserDelete 删除成员
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90334
|
||||
func (r *Client) UserDelete(userID string) (*UserDeleteResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(strings.Join([]string{
|
||||
userDeleteURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
"userid": userID,
|
||||
}),
|
||||
}, "?")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UserDeleteResponse{}
|
||||
err = util.DecodeWithError(response, result, "UserDelete")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UserListIDRequest 获取成员ID列表请求
|
||||
@@ -166,12 +305,95 @@ func (r *Client) UserListID(req *UserListIDRequest) (*UserListIDResponse, error)
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(UserListIDURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(strings.Join([]string{
|
||||
userListIDURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
}),
|
||||
}, "?"), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UserListIDResponse{}
|
||||
if err = util.DecodeWithError(response, result, "UserListID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "UserListID")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// convertToOpenIDRequest userID转openID请求
|
||||
convertToOpenIDRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
}
|
||||
|
||||
// convertToOpenIDResponse userID转openID响应
|
||||
convertToOpenIDResponse struct {
|
||||
util.CommonError
|
||||
OpenID string `json:"openid"`
|
||||
}
|
||||
)
|
||||
|
||||
// ConvertToOpenID userID转openID
|
||||
// see https://developer.work.weixin.qq.com/document/path/90202
|
||||
func (r *Client) ConvertToOpenID(userID string) (string, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
var response []byte
|
||||
|
||||
if response, err = util.PostJSON(strings.Join([]string{
|
||||
convertToOpenIDURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
}),
|
||||
}, "?"), &convertToOpenIDRequest{
|
||||
UserID: userID,
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
result := &convertToOpenIDResponse{}
|
||||
err = util.DecodeWithError(response, result, "ConvertToOpenID")
|
||||
return result.OpenID, err
|
||||
}
|
||||
|
||||
type (
|
||||
// convertToUserIDRequest openID转userID请求
|
||||
convertToUserIDRequest struct {
|
||||
OpenID string `json:"openid"`
|
||||
}
|
||||
|
||||
// convertToUserIDResponse openID转userID响应
|
||||
convertToUserIDResponse struct {
|
||||
util.CommonError
|
||||
UserID string `json:"userid"`
|
||||
}
|
||||
)
|
||||
|
||||
// ConvertToUserID openID转userID
|
||||
// see https://developer.work.weixin.qq.com/document/path/90202
|
||||
func (r *Client) ConvertToUserID(openID string) (string, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
var response []byte
|
||||
|
||||
if response, err = util.PostJSON(strings.Join([]string{
|
||||
convertToUserIDURL,
|
||||
util.Query(map[string]interface{}{
|
||||
"access_token": accessToken,
|
||||
}),
|
||||
}, "?"), &convertToUserIDRequest{
|
||||
OpenID: openID,
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
result := &convertToUserIDResponse{}
|
||||
err = util.DecodeWithError(response, result, "ConvertToUserID")
|
||||
return result.UserID, err
|
||||
}
|
||||
|
||||
113
work/appchat/appchat.go
Normal file
113
work/appchat/appchat.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package appchat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// 应用推送消息接口地址
|
||||
sendURL = "https://qyapi.weixin.qq.com/cgi-bin/appchat/send?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
// SendRequestCommon 发送应用推送消息请求公共参数
|
||||
SendRequestCommon struct {
|
||||
// 群聊id
|
||||
ChatID string `json:"chatid"`
|
||||
// 消息类型
|
||||
MsgType string `json:"msgtype"`
|
||||
// 表示是否是保密消息,0表示否,1表示是,默认0
|
||||
Safe int `json:"safe"`
|
||||
}
|
||||
|
||||
// SendResponse 发送应用消息响应参数
|
||||
SendResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
|
||||
// SendTextRequest 发送文本消息的请求
|
||||
SendTextRequest struct {
|
||||
*SendRequestCommon
|
||||
Text TextField `json:"text"`
|
||||
}
|
||||
// TextField 文本消息参数
|
||||
TextField struct {
|
||||
// 消息内容,最长不超过2048个字节
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// SendImageRequest 发送图片消息的请求
|
||||
SendImageRequest struct {
|
||||
*SendRequestCommon
|
||||
Image ImageField `json:"image"`
|
||||
}
|
||||
// ImageField 图片消息参数
|
||||
ImageField struct {
|
||||
// 图片媒体文件id,可以调用上传临时素材接口获取
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// SendVoiceRequest 发送语音消息的请求
|
||||
SendVoiceRequest struct {
|
||||
*SendRequestCommon
|
||||
Voice VoiceField `json:"voice"`
|
||||
}
|
||||
// VoiceField 语音消息参数
|
||||
VoiceField struct {
|
||||
// 语音文件id,可以调用上传临时素材接口获取
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
)
|
||||
|
||||
// Send 发送应用消息
|
||||
// @desc 实现企业微信发送应用消息接口:https://developer.work.weixin.qq.com/document/path/90248
|
||||
func (r *Client) Send(apiName string, request interface{}) (*SendResponse, error) {
|
||||
// 获取accessToken
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 请求参数转 JSON 格式
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 发起http请求
|
||||
response, err := util.HTTPPost(fmt.Sprintf(sendURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 按照结构体解析返回值
|
||||
result := &SendResponse{}
|
||||
err = util.DecodeWithError(response, result, apiName)
|
||||
// 返回数据
|
||||
return result, err
|
||||
}
|
||||
|
||||
// SendText 发送文本消息
|
||||
func (r *Client) SendText(request SendTextRequest) (*SendResponse, error) {
|
||||
// 发送文本消息MsgType参数固定为:text
|
||||
request.MsgType = "text"
|
||||
return r.Send("MessageSendText", request)
|
||||
}
|
||||
|
||||
// SendImage 发送图片消息
|
||||
func (r *Client) SendImage(request SendImageRequest) (*SendResponse, error) {
|
||||
// 发送图片消息MsgType参数固定为:image
|
||||
request.MsgType = "image"
|
||||
return r.Send("MessageSendImage", request)
|
||||
}
|
||||
|
||||
// SendVoice 发送语音消息
|
||||
func (r *Client) SendVoice(request SendVoiceRequest) (*SendResponse, error) {
|
||||
// 发送语音消息MsgType参数固定为:voice
|
||||
request.MsgType = "voice"
|
||||
return r.Send("MessageSendVoice", request)
|
||||
}
|
||||
|
||||
// 以上实现了部分常用消息推送:SendText 发送文本消息、SendImage 发送图片消息、SendVoice 发送语音消息,
|
||||
// 如需扩展其他消息类型,建议按照以上格式,扩展对应消息类型的参数即可
|
||||
// 也可以直接使用Send方法,按照企业微信消息推送的接口文档传对应消息类型的参数来使用
|
||||
16
work/appchat/client.go
Normal file
16
work/appchat/client.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Package appchat 应用发送消息到群聊会话,企业微信接口:https://developer.work.weixin.qq.com/document/path/90248
|
||||
package appchat
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/work/context"
|
||||
)
|
||||
|
||||
// Client 接口实例
|
||||
type Client struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewClient 初始化实例
|
||||
func NewClient(ctx *context.Context) *Client {
|
||||
return &Client{ctx}
|
||||
}
|
||||
387
work/checkin/checkin.go
Normal file
387
work/checkin/checkin.go
Normal file
@@ -0,0 +1,387 @@
|
||||
package checkin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// setScheduleListURL 为打卡人员排班
|
||||
setScheduleListURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/setcheckinschedulist?access_token=%s"
|
||||
// punchCorrectionURL 为打卡人员补卡
|
||||
punchCorrectionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/punch_correction?access_token=%s"
|
||||
// addUserFaceURL 录入打卡人员人脸信息
|
||||
addUserFaceURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/addcheckinuserface?access_token=%s"
|
||||
// addOptionURL 创建打卡规则
|
||||
addOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/add_checkin_option?access_token=%s"
|
||||
// updateOptionURL 修改打卡规则
|
||||
updateOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/update_checkin_option?access_token=%s"
|
||||
// clearOptionURL 清空打卡规则数组元素
|
||||
clearOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/clear_checkin_option_array_field?access_token=%s"
|
||||
// delOptionURL 删除打卡规则
|
||||
delOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/del_checkin_option?access_token=%s"
|
||||
)
|
||||
|
||||
// SetScheduleListRequest 为打卡人员排班请求
|
||||
type SetScheduleListRequest struct {
|
||||
GroupID int64 `json:"groupid"`
|
||||
Items []SetScheduleListItem `json:"items"`
|
||||
YearMonth int64 `json:"yearmonth"`
|
||||
}
|
||||
|
||||
// SetScheduleListItem 排班表信息
|
||||
type SetScheduleListItem struct {
|
||||
UserID string `json:"userid"`
|
||||
Day int64 `json:"day"`
|
||||
ScheduleID int64 `json:"schedule_id"`
|
||||
}
|
||||
|
||||
// SetScheduleList 为打卡人员排班
|
||||
// see https://developer.work.weixin.qq.com/document/path/93385
|
||||
func (r *Client) SetScheduleList(req *SetScheduleListRequest) 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(setScheduleListURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "SetScheduleList")
|
||||
}
|
||||
|
||||
// PunchCorrectionRequest 为打卡人员补卡请求
|
||||
type PunchCorrectionRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
ScheduleDateTime int64 `json:"schedule_date_time"`
|
||||
ScheduleCheckinTime int64 `json:"schedule_checkin_time"`
|
||||
CheckinTime int64 `json:"checkin_time"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// PunchCorrection 为打卡人员补卡
|
||||
// see https://developer.work.weixin.qq.com/document/path/95803
|
||||
func (r *Client) PunchCorrection(req *PunchCorrectionRequest) 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(punchCorrectionURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "PunchCorrection")
|
||||
}
|
||||
|
||||
// AddUserFaceRequest 录入打卡人员人脸信息请求
|
||||
type AddUserFaceRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
UserFace string `json:"userface"`
|
||||
}
|
||||
|
||||
// AddUserFace 录入打卡人员人脸信息
|
||||
// see https://developer.work.weixin.qq.com/document/path/93378
|
||||
func (r *Client) AddUserFace(req *AddUserFaceRequest) 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(addUserFaceURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "AddUserFace")
|
||||
}
|
||||
|
||||
// AddOptionRequest 创建打卡规则请求
|
||||
type AddOptionRequest struct {
|
||||
EffectiveNow bool `json:"effective_now,omitempty"`
|
||||
Group OptionGroupRule `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
// OptionGroupRule 打卡规则字段
|
||||
type OptionGroupRule struct {
|
||||
GroupID int64 `json:"groupid,omitempty"`
|
||||
GroupType int64 `json:"grouptype"`
|
||||
GroupName string `json:"groupname"`
|
||||
CheckinDate []OptionGroupRuleCheckinDate `json:"checkindate,omitempty"`
|
||||
SpeWorkdays []OptionGroupSpeWorkdays `json:"spe_workdays,omitempty"`
|
||||
SpeOffDays []OptionGroupSpeOffDays `json:"spe_offdays,omitempty"`
|
||||
SyncHolidays bool `json:"sync_holidays,omitempty"`
|
||||
NeedPhoto bool `json:"need_photo,omitempty"`
|
||||
NoteCanUseLocalPic bool `json:"note_can_use_local_pic,omitempty"`
|
||||
WifiMacInfos []OptionGroupWifiMacInfos `json:"wifimac_infos,omitempty"`
|
||||
LocInfos []OptionGroupLocInfos `json:"loc_infos,omitempty"`
|
||||
AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday,omitempty"`
|
||||
AllowApplyOffWorkday bool `json:"allow_apply_offworkday,omitempty"`
|
||||
Range []OptionGroupRange `json:"range"`
|
||||
WhiteUsers []string `json:"white_users,omitempty"`
|
||||
Type int64 `json:"type,omitempty"`
|
||||
ReporterInfo OptionGroupReporterInfo `json:"reporterinfo,omitempty"`
|
||||
AllowApplyBkCnt int64 `json:"allow_apply_bk_cnt,omitempty"`
|
||||
AllowApplyBkDayLimit int64 `json:"allow_apply_bk_day_limit,omitempty"`
|
||||
BukaLimitNextMonth int64 `json:"buka_limit_next_month,omitempty"`
|
||||
OptionOutRange int64 `json:"option_out_range,omitempty"`
|
||||
ScheduleList []OptionGroupScheduleList `json:"schedulelist,omitempty"`
|
||||
OffWorkIntervalTime int64 `json:"offwork_interval_time,omitempty"`
|
||||
UseFaceDetect bool `json:"use_face_detect,omitempty"`
|
||||
OpenFaceLiveDetect bool `json:"open_face_live_detect,omitempty"`
|
||||
OtInfoV2 OptionGroupOtInfoV2 `json:"ot_info_v2,omitempty"`
|
||||
SyncOutCheckin bool `json:"sync_out_checkin,omitempty"`
|
||||
BukaRemind OptionGroupBukaRemind `json:"buka_remind,omitempty"`
|
||||
BukaRestriction int64 `json:"buka_restriction,omitempty"`
|
||||
SpanDayTime int64 `json:"span_day_time,omitempty"`
|
||||
StandardWorkDuration int64 `json:"standard_work_duration,omitempty"`
|
||||
}
|
||||
|
||||
// OptionGroupRuleCheckinDate 固定时间上下班打卡时间
|
||||
type OptionGroupRuleCheckinDate struct {
|
||||
Workdays []int64 `json:"workdays"`
|
||||
CheckinTime []OptionGroupRuleCheckinTime `json:"checkintime"`
|
||||
FlexTime int64 `json:"flex_time"`
|
||||
AllowFlex bool `json:"allow_flex"`
|
||||
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
|
||||
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
|
||||
MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"`
|
||||
MaxAllowArriveLate int64 `json:"max_allow_arrive_late"`
|
||||
LateRule OptionGroupLateRule `json:"late_rule"`
|
||||
}
|
||||
|
||||
// OptionGroupRuleCheckinTime 工作日上下班打卡时间信息
|
||||
type OptionGroupRuleCheckinTime struct {
|
||||
TimeID int64 `json:"time_id"`
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
AllowRest bool `json:"allow_rest"`
|
||||
RestBeginTime int64 `json:"rest_begin_time"`
|
||||
RestEndTime int64 `json:"rest_end_time"`
|
||||
EarliestWorkSec int64 `json:"earliest_work_sec"`
|
||||
LatestWorkSec int64 `json:"latest_work_sec"`
|
||||
EarliestOffWorkSec int64 `json:"earliest_off_work_sec"`
|
||||
LatestOffWorkSec int64 `json:"latest_off_work_sec"`
|
||||
NoNeedCheckOn bool `json:"no_need_checkon"`
|
||||
NoNeedCheckOff bool `json:"no_need_checkoff"`
|
||||
}
|
||||
|
||||
// OptionGroupLateRule 晚走晚到时间规则信息
|
||||
type OptionGroupLateRule struct {
|
||||
OffWorkAfterTime int64 `json:"offwork_after_time"`
|
||||
OnWorkFlexTime int64 `json:"onwork_flex_time"`
|
||||
AllowOffWorkAfterTime int64 `json:"allow_offwork_after_time"`
|
||||
TimeRules []OptionGroupTimeRule `json:"timerules"`
|
||||
}
|
||||
|
||||
// OptionGroupTimeRule 晚走晚到时间规则
|
||||
type OptionGroupTimeRule struct {
|
||||
OffWorkAfterTime int64 `json:"offwork_after_time"`
|
||||
OnWorkFlexTime int64 `json:"onwork_flex_time"`
|
||||
}
|
||||
|
||||
// OptionGroupSpeWorkdays 特殊工作日
|
||||
type OptionGroupSpeWorkdays struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Notes string `json:"notes"`
|
||||
CheckinTime []OptionGroupCheckinTime `json:"checkintime"`
|
||||
Type int64 `json:"type"`
|
||||
BegTime int64 `json:"begtime"`
|
||||
EndTime int64 `json:"endtime"`
|
||||
}
|
||||
|
||||
// OptionGroupCheckinTime 特殊工作日的上下班打卡时间配置
|
||||
type OptionGroupCheckinTime struct {
|
||||
TimeID int64 `json:"time_id"`
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
}
|
||||
|
||||
// OptionGroupSpeOffDays 特殊非工作日
|
||||
type OptionGroupSpeOffDays struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Notes string `json:"notes"`
|
||||
Type int64 `json:"type"`
|
||||
BegTime int64 `json:"begtime"`
|
||||
EndTime int64 `json:"endtime"`
|
||||
}
|
||||
|
||||
// OptionGroupWifiMacInfos WIFI信息
|
||||
type OptionGroupWifiMacInfos struct {
|
||||
WifiName string `json:"wifiname"`
|
||||
WifiMac string `json:"wifimac"`
|
||||
}
|
||||
|
||||
// OptionGroupLocInfos 地点信息
|
||||
type OptionGroupLocInfos struct {
|
||||
Lat int64 `json:"lat"`
|
||||
Lng int64 `json:"lng"`
|
||||
LocTitle string `json:"loc_title"`
|
||||
LocDetail string `json:"loc_detail"`
|
||||
Distance int64 `json:"distance"`
|
||||
}
|
||||
|
||||
// OptionGroupRange 人员信息
|
||||
type OptionGroupRange struct {
|
||||
PartyID []string `json:"party_id"`
|
||||
UserID []string `json:"userid"`
|
||||
TagID []int64 `json:"tagid"`
|
||||
}
|
||||
|
||||
// OptionGroupReporterInfo 汇报人
|
||||
type OptionGroupReporterInfo struct {
|
||||
Reporters []OptionGroupReporters `json:"reporters"`
|
||||
}
|
||||
|
||||
// OptionGroupReporters 汇报对象
|
||||
type OptionGroupReporters struct {
|
||||
UserID string `json:"userid"`
|
||||
TagID int64 `json:"tagid"`
|
||||
}
|
||||
|
||||
// OptionGroupScheduleList 自定义排班规则所有排班
|
||||
type OptionGroupScheduleList struct {
|
||||
ScheduleID int64 `json:"schedule_id"`
|
||||
ScheduleName string `json:"schedule_name"`
|
||||
TimeSection []OptionGroupTimeSection `json:"time_section"`
|
||||
AllowFlex bool `json:"allow_flex"`
|
||||
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
|
||||
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
|
||||
LateRule OptionGroupLateRule `json:"late_rule"`
|
||||
MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"`
|
||||
MaxAllowArriveLate int64 `json:"max_allow_arrive_late"`
|
||||
}
|
||||
|
||||
// OptionGroupTimeSection 班次上下班时段信息
|
||||
type OptionGroupTimeSection struct {
|
||||
TimeID int64 `json:"time_id"`
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
RestBeginTime int64 `json:"rest_begin_time"`
|
||||
RestEndTime int64 `json:"rest_end_time"`
|
||||
AllowRest bool `json:"allow_rest"`
|
||||
EarliestWorkSec int64 `json:"earliest_work_sec"`
|
||||
LatestWorkSec int64 `json:"latest_work_sec"`
|
||||
EarliestOffWorkSec int64 `json:"earliest_off_work_sec"`
|
||||
LatestOffWorkSec int64 `json:"latest_off_work_sec"`
|
||||
NoNeedCheckOn bool `json:"no_need_checkon"`
|
||||
NoNeedCheckOff bool `json:"no_need_checkoff"`
|
||||
}
|
||||
|
||||
// OptionGroupOtInfoV2 加班配置
|
||||
type OptionGroupOtInfoV2 struct {
|
||||
WorkdayConf OptionGroupWorkdayConf `json:"workdayconf"`
|
||||
}
|
||||
|
||||
// OptionGroupWorkdayConf 工作日加班配置
|
||||
type OptionGroupWorkdayConf struct {
|
||||
AllowOt bool `json:"allow_ot"`
|
||||
Type int64 `json:"type"`
|
||||
}
|
||||
|
||||
// OptionGroupBukaRemind 补卡提醒
|
||||
type OptionGroupBukaRemind struct {
|
||||
OpenRemind bool `json:"open_remind"`
|
||||
BukaRemindDay int64 `json:"buka_remind_day"`
|
||||
BukaRemindMonth int64 `json:"buka_remind_month"`
|
||||
}
|
||||
|
||||
// AddOption 创建打卡规则
|
||||
// see https://developer.work.weixin.qq.com/document/path/98041#%E5%88%9B%E5%BB%BA%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
|
||||
func (r *Client) AddOption(req *AddOptionRequest) 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(addOptionURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "AddOption")
|
||||
}
|
||||
|
||||
// UpdateOptionRequest 修改打卡规则请求
|
||||
type UpdateOptionRequest struct {
|
||||
EffectiveNow bool `json:"effective_now,omitempty"`
|
||||
Group OptionGroupRule `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateOption 修改打卡规则
|
||||
// see https://developer.work.weixin.qq.com/document/path/98041#%E4%BF%AE%E6%94%B9%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
|
||||
func (r *Client) UpdateOption(req *UpdateOptionRequest) 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(updateOptionURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateOption")
|
||||
}
|
||||
|
||||
// ClearOptionRequest 清空打卡规则数组元素请求
|
||||
type ClearOptionRequest struct {
|
||||
GroupID int64 `json:"groupid"`
|
||||
ClearField []int64 `json:"clear_field"`
|
||||
EffectiveNow bool `json:"effective_now"`
|
||||
}
|
||||
|
||||
// ClearOption 清空打卡规则数组元素
|
||||
// see https://developer.work.weixin.qq.com/document/path/98041#%E6%B8%85%E7%A9%BA%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99%E6%95%B0%E7%BB%84%E5%85%83%E7%B4%A0
|
||||
func (r *Client) ClearOption(req *ClearOptionRequest) 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(clearOptionURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "ClearOption")
|
||||
}
|
||||
|
||||
// DelOptionRequest 删除打卡规则请求
|
||||
type DelOptionRequest struct {
|
||||
GroupID int64 `json:"groupid"`
|
||||
EffectiveNow bool `json:"effective_now"`
|
||||
}
|
||||
|
||||
// DelOption 删除打卡规则
|
||||
// see https://developer.work.weixin.qq.com/document/path/98041#%E5%88%A0%E9%99%A4%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
|
||||
func (r *Client) DelOption(req *DelOptionRequest) 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(delOptionURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelOption")
|
||||
}
|
||||
17
work/checkin/client.go
Normal file
17
work/checkin/client.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package checkin
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/work/context"
|
||||
)
|
||||
|
||||
// Client 打卡接口实例
|
||||
type Client struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewClient 初始化实例
|
||||
func NewClient(ctx *context.Context) *Client {
|
||||
return &Client{
|
||||
ctx,
|
||||
}
|
||||
}
|
||||
660
work/checkin/record.go
Normal file
660
work/checkin/record.go
Normal file
@@ -0,0 +1,660 @@
|
||||
package checkin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// getCheckinDataURL 获取打卡记录数据
|
||||
getCheckinDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=%s"
|
||||
// getDayDataURL 获取打卡日报数据
|
||||
getDayDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckin_daydata?access_token=%s"
|
||||
// getMonthDataURL 获取打卡月报数据
|
||||
getMonthDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckin_monthdata?access_token=%s"
|
||||
// getCorpOptionURL 获取企业所有打卡规则
|
||||
getCorpOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption?access_token=%s"
|
||||
// getOptionURL 获取员工打卡规则
|
||||
getOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinoption?access_token=%s"
|
||||
// getScheduleListURL 获取打卡人员排班信息
|
||||
getScheduleListURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinschedulist?access_token=%s"
|
||||
// getHardwareDataURL获取设备打卡数据
|
||||
getHardwareDataURL = "https://qyapi.weixin.qq.com/cgi-bin/hardware/get_hardware_checkin_data?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
// GetCheckinDataRequest 获取打卡记录数据请求
|
||||
GetCheckinDataRequest struct {
|
||||
OpenCheckinDataType int64 `json:"opencheckindatatype"`
|
||||
StartTime int64 `json:"starttime"`
|
||||
EndTime int64 `json:"endtime"`
|
||||
UserIDList []string `json:"useridlist"`
|
||||
}
|
||||
// GetCheckinDataResponse 获取打卡记录数据响应
|
||||
GetCheckinDataResponse struct {
|
||||
util.CommonError
|
||||
CheckinData []*GetCheckinDataItem `json:"checkindata"`
|
||||
}
|
||||
// GetCheckinDataItem 打卡记录数据
|
||||
GetCheckinDataItem struct {
|
||||
UserID string `json:"userid"`
|
||||
GroupName string `json:"groupname"`
|
||||
CheckinType string `json:"checkin_type"`
|
||||
ExceptionType string `json:"exception_type"`
|
||||
CheckinTime int64 `json:"checkin_time"`
|
||||
LocationTitle string `json:"location_title"`
|
||||
LocationDetail string `json:"location_detail"`
|
||||
WifiName string `json:"wifiname"`
|
||||
Notes string `json:"notes"`
|
||||
WifiMac string `json:"wifimac"`
|
||||
MediaIDs []string `json:"mediaids"`
|
||||
SchCheckinTime int64 `json:"sch_checkin_time"`
|
||||
GroupID int64 `json:"groupid"`
|
||||
ScheduleID int64 `json:"schedule_id"`
|
||||
TimelineID int64 `json:"timeline_id"`
|
||||
Lat int64 `json:"lat,omitempty"`
|
||||
Lng int64 `json:"lng,omitempty"`
|
||||
DeviceID string `json:"deviceid,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetCheckinData 获取打卡记录数据
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90262
|
||||
func (r *Client) GetCheckinData(req *GetCheckinDataRequest) (*GetCheckinDataResponse, 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(getCheckinDataURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCheckinDataResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCheckinData")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// GetDayDataResponse 获取打卡日报数据
|
||||
GetDayDataResponse struct {
|
||||
util.CommonError
|
||||
Datas []DayDataItem `json:"datas"`
|
||||
}
|
||||
|
||||
// DayDataItem 日报
|
||||
DayDataItem struct {
|
||||
BaseInfo DayBaseInfo `json:"base_info"`
|
||||
SummaryInfo DaySummaryInfo `json:"summary_info"`
|
||||
HolidayInfos []HolidayInfo `json:"holiday_infos"`
|
||||
ExceptionInfos []ExceptionInfo `json:"exception_infos"`
|
||||
OtInfo OtInfo `json:"ot_info"`
|
||||
SpItems []SpItem `json:"sp_items"`
|
||||
}
|
||||
|
||||
// DayBaseInfo 基础信息
|
||||
DayBaseInfo struct {
|
||||
Date int64 `json:"date"`
|
||||
RecordType int64 `json:"record_type"`
|
||||
Name string `json:"name"`
|
||||
NameEx string `json:"name_ex"`
|
||||
DepartsName string `json:"departs_name"`
|
||||
AcctID string `json:"acctid"`
|
||||
DayType int64 `json:"day_type"`
|
||||
RuleInfo DayRuleInfo `json:"rule_info"`
|
||||
}
|
||||
|
||||
// DayCheckInTime 当日打卡时间
|
||||
DayCheckInTime struct {
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
}
|
||||
|
||||
// DayRuleInfo 打卡人员所属规则信息
|
||||
DayRuleInfo struct {
|
||||
GroupID int64 `json:"groupid"`
|
||||
GroupName string `json:"groupname"`
|
||||
ScheduleID int64 `json:"scheduleid"`
|
||||
ScheduleName string `json:"schedulename"`
|
||||
CheckInTimes []DayCheckInTime `json:"checkintime"`
|
||||
}
|
||||
|
||||
// DaySummaryInfo 汇总信息
|
||||
DaySummaryInfo struct {
|
||||
CheckinCount int64 `json:"checkin_count"`
|
||||
RegularWorkSec int64 `json:"regular_work_sec"`
|
||||
StandardWorkSec int64 `json:"standard_work_sec"`
|
||||
EarliestTime int64 `json:"earliest_time"`
|
||||
LastestTime int64 `json:"lastest_time"`
|
||||
}
|
||||
|
||||
// HolidayInfo 假勤相关信息
|
||||
HolidayInfo struct {
|
||||
SpNumber string `json:"sp_number"`
|
||||
SpTitle SpTitle `json:"sp_title"`
|
||||
SpDescription SpDescription `json:"sp_description"`
|
||||
}
|
||||
|
||||
// SpTitle 假勤信息摘要-标题信息
|
||||
SpTitle struct {
|
||||
Data []SpData `json:"data"`
|
||||
}
|
||||
|
||||
// SpDescription 假勤信息摘要-描述信息
|
||||
SpDescription struct {
|
||||
Data []SpData `json:"data"`
|
||||
}
|
||||
|
||||
// SpData 假勤信息(多种语言描述,目前只有中文一种)
|
||||
SpData struct {
|
||||
Lang string `json:"lang"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// SpItem 假勤统计信息
|
||||
SpItem struct {
|
||||
Count int64 `json:"count"`
|
||||
Duration int64 `json:"duration"`
|
||||
TimeType int64 `json:"time_type"`
|
||||
Type int64 `json:"type"`
|
||||
VacationID int64 `json:"vacation_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ExceptionInfo 校准状态信息
|
||||
ExceptionInfo struct {
|
||||
Count int64 `json:"count"`
|
||||
Duration int64 `json:"duration"`
|
||||
Exception int64 `json:"exception"`
|
||||
}
|
||||
|
||||
// OtInfo 加班信息
|
||||
OtInfo struct {
|
||||
OtStatus int64 `json:"ot_status"`
|
||||
OtDuration int64 `json:"ot_duration"`
|
||||
ExceptionDuration []uint64 `json:"exception_duration"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetDayData 获取打卡日报数据
|
||||
// @see https://developer.work.weixin.qq.com/document/path/96498
|
||||
func (r *Client) GetDayData(req *GetCheckinDataRequest) (result *GetDayDataResponse, err error) {
|
||||
var (
|
||||
response []byte
|
||||
accessToken string
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return
|
||||
}
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getDayDataURL, accessToken), req); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = new(GetDayDataResponse)
|
||||
err = util.DecodeWithError(response, result, "GetDayData")
|
||||
return
|
||||
}
|
||||
|
||||
type (
|
||||
// GetMonthDataResponse 获取打卡月报数据
|
||||
GetMonthDataResponse struct {
|
||||
util.CommonError
|
||||
Datas []MonthDataItem `json:"datas"`
|
||||
}
|
||||
|
||||
// MonthDataItem 月报数据
|
||||
MonthDataItem struct {
|
||||
BaseInfo MonthBaseInfo `json:"base_info"`
|
||||
SummaryInfo MonthSummaryInfo `json:"summary_info"`
|
||||
ExceptionInfos []ExceptionInfo `json:"exception_infos"`
|
||||
SpItems []SpItem `json:"sp_items"`
|
||||
OverWorkInfo OverWorkInfo `json:"overwork_info"`
|
||||
}
|
||||
|
||||
// MonthBaseInfo 基础信息
|
||||
MonthBaseInfo struct {
|
||||
RecordType int64 `json:"record_type"`
|
||||
Name string `json:"name"`
|
||||
NameEx string `json:"name_ex"`
|
||||
DepartsName string `json:"departs_name"`
|
||||
AcctID string `json:"acctid"`
|
||||
RuleInfo MonthRuleInfo `json:"rule_info"`
|
||||
}
|
||||
|
||||
// MonthRuleInfo 打卡人员所属规则信息
|
||||
MonthRuleInfo struct {
|
||||
GroupID int64 `json:"groupid"`
|
||||
GroupName string `json:"groupname"`
|
||||
}
|
||||
|
||||
// MonthSummaryInfo 汇总信息
|
||||
MonthSummaryInfo struct {
|
||||
WorkDays int64 `json:"work_days"`
|
||||
ExceptDays int64 `json:"except_days"`
|
||||
RegularDays int64 `json:"regular_days"`
|
||||
RegularWorkSec int64 `json:"regular_work_sec"`
|
||||
StandardWorkSec int64 `json:"standard_work_sec"`
|
||||
}
|
||||
|
||||
// OverWorkInfo 加班情况
|
||||
OverWorkInfo struct {
|
||||
WorkdayOverSec int64 `json:"workday_over_sec"`
|
||||
HolidayOverSec int64 `json:"holidays_over_sec"`
|
||||
RestDayOverSec int64 `json:"restdays_over_sec"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetMonthData 获取打卡月报数据
|
||||
// @see https://developer.work.weixin.qq.com/document/path/96499
|
||||
func (r *Client) GetMonthData(req *GetCheckinDataRequest) (result *GetMonthDataResponse, err error) {
|
||||
var (
|
||||
response []byte
|
||||
accessToken string
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return
|
||||
}
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getMonthDataURL, accessToken), req); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = new(GetMonthDataResponse)
|
||||
err = util.DecodeWithError(response, result, "GetMonthData")
|
||||
return
|
||||
}
|
||||
|
||||
// GetCorpOptionResponse 获取企业所有打卡规则响应
|
||||
type GetCorpOptionResponse struct {
|
||||
util.CommonError
|
||||
Group []CorpOptionGroup `json:"group"`
|
||||
}
|
||||
|
||||
// CorpOptionGroup 企业规则信息列表
|
||||
type CorpOptionGroup struct {
|
||||
GroupType int64 `json:"grouptype"`
|
||||
GroupID int64 `json:"groupid"`
|
||||
GroupName string `json:"groupname"`
|
||||
CheckinDate []GroupCheckinDate `json:"checkindate"`
|
||||
SpeWorkdays []SpeWorkdays `json:"spe_workdays"`
|
||||
SpeOffDays []SpeOffDays `json:"spe_offdays"`
|
||||
SyncHolidays bool `json:"sync_holidays"`
|
||||
NeedPhoto bool `json:"need_photo"`
|
||||
NoteCanUseLocalPic bool `json:"note_can_use_local_pic"`
|
||||
AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday"`
|
||||
AllowApplyOffWorkday bool `json:"allow_apply_offworkday"`
|
||||
WifiMacInfos []WifiMacInfos `json:"wifimac_infos"`
|
||||
LocInfos []LocInfos `json:"loc_infos"`
|
||||
Range []Range `json:"range"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
WhiteUsers []string `json:"white_users"`
|
||||
Type int64 `json:"type"`
|
||||
ReporterInfo ReporterInfo `json:"reporterinfo"`
|
||||
OtInfo GroupOtInfo `json:"ot_info"`
|
||||
OtApplyInfo OtApplyInfo `json:"otapplyinfo"`
|
||||
Uptime int64 `json:"uptime"`
|
||||
AllowApplyBkCnt int64 `json:"allow_apply_bk_cnt"`
|
||||
OptionOutRange int64 `json:"option_out_range"`
|
||||
CreateUserID string `json:"create_userid"`
|
||||
UseFaceDetect bool `json:"use_face_detect"`
|
||||
AllowApplyBkDayLimit int64 `json:"allow_apply_bk_day_limit"`
|
||||
UpdateUserID string `json:"update_userid"`
|
||||
BukaRestriction int64 `json:"buka_restriction"`
|
||||
ScheduleList []ScheduleList `json:"schedulelist"`
|
||||
OffWorkIntervalTime int64 `json:"offwork_interval_time"`
|
||||
}
|
||||
|
||||
// GroupCheckinDate 打卡时间,当规则类型为排班时没有意义
|
||||
type GroupCheckinDate struct {
|
||||
Workdays []int64 `json:"workdays"`
|
||||
CheckinTime []GroupCheckinTime `json:"checkintime"`
|
||||
NoNeedOffWork bool `json:"noneed_offwork"`
|
||||
LimitAheadTime int64 `json:"limit_aheadtime"`
|
||||
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
|
||||
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
|
||||
}
|
||||
|
||||
// GroupCheckinTime 工作日上下班打卡时间信息
|
||||
type GroupCheckinTime struct {
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
}
|
||||
|
||||
// SpeWorkdays 特殊日期-必须打卡日期信息
|
||||
type SpeWorkdays struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Notes string `json:"notes"`
|
||||
CheckinTime []GroupCheckinTime `json:"checkintime"`
|
||||
}
|
||||
|
||||
// SpeOffDays 特殊日期-不用打卡日期信息
|
||||
type SpeOffDays struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Notes string `json:"notes"`
|
||||
}
|
||||
|
||||
// WifiMacInfos 打卡地点-WiFi打卡信息
|
||||
type WifiMacInfos struct {
|
||||
WifiName string `json:"wifiname"`
|
||||
WifiMac string `json:"wifimac"`
|
||||
}
|
||||
|
||||
// LocInfos 打卡地点-位置打卡信息
|
||||
type LocInfos struct {
|
||||
Lat int64 `json:"lat"`
|
||||
Lng int64 `json:"lng"`
|
||||
LocTitle string `json:"loc_title"`
|
||||
LocDetail string `json:"loc_detail"`
|
||||
Distance int64 `json:"distance"`
|
||||
}
|
||||
|
||||
// Range 打卡人员信息
|
||||
type Range struct {
|
||||
PartyID []string `json:"partyid"`
|
||||
UserID []string `json:"userid"`
|
||||
TagID []int64 `json:"tagid"`
|
||||
}
|
||||
|
||||
// ReporterInfo 汇报对象信息
|
||||
type ReporterInfo struct {
|
||||
Reporters []Reporters `json:"reporters"`
|
||||
UpdateTime int64 `json:"updatetime"`
|
||||
}
|
||||
|
||||
// Reporters 汇报对象,每个汇报人用userid表示
|
||||
type Reporters struct {
|
||||
UserID string `json:"userid"`
|
||||
}
|
||||
|
||||
// GroupOtInfo 加班信息
|
||||
type GroupOtInfo struct {
|
||||
Type int64 `json:"type"`
|
||||
AllowOtWorkingDay bool `json:"allow_ot_workingday"`
|
||||
AllowOtNonWorkingDay bool `json:"allow_ot_nonworkingday"`
|
||||
OtCheckInfo OtCheckInfo `json:"otcheckinfo"`
|
||||
}
|
||||
|
||||
// OtCheckInfo 以打卡时间为准-加班时长计算规则信息
|
||||
type OtCheckInfo struct {
|
||||
OtWorkingDayTimeStart int64 `json:"ot_workingday_time_start"`
|
||||
OtWorkingDayTimeMin int64 `json:"ot_workingday_time_min"`
|
||||
OtWorkingDayTimeMax int64 `json:"ot_workingday_time_max"`
|
||||
OtNonworkingDayTimeMin int64 `json:"ot_nonworkingday_time_min"`
|
||||
OtNonworkingDayTimeMax int64 `json:"ot_nonworkingday_time_max"`
|
||||
OtNonworkingDaySpanDayTime int64 `json:"ot_nonworkingday_spanday_time"`
|
||||
OtWorkingDayRestInfo OtRestInfo `json:"ot_workingday_restinfo"`
|
||||
OtNonWorkingDayRestInfo OtRestInfo `json:"ot_nonworkingday_restinfo"`
|
||||
}
|
||||
|
||||
// OtRestInfo 加班-休息扣除配置信息
|
||||
type OtRestInfo struct {
|
||||
Type int64 `json:"type"`
|
||||
FixTimeRule FixTimeRule `json:"fix_time_rule"`
|
||||
CalOtTimeRule CalOtTimeRule `json:"cal_ottime_rule"`
|
||||
}
|
||||
|
||||
// FixTimeRule 工作日加班-指定休息时间配置信息
|
||||
type FixTimeRule struct {
|
||||
FixTimeBeginSec int64 `json:"fix_time_begin_sec"`
|
||||
FixTimeEndSec int64 `json:"fix_time_end_sec"`
|
||||
}
|
||||
|
||||
// CalOtTimeRule 工作日加班-按加班时长扣除配置信息
|
||||
type CalOtTimeRule struct {
|
||||
Items []CalOtTimeRuleItem `json:"items"`
|
||||
}
|
||||
|
||||
// CalOtTimeRuleItem 工作日加班-按加班时长扣除条件信息
|
||||
type CalOtTimeRuleItem struct {
|
||||
OtTime int64 `json:"ot_time"`
|
||||
RestTime int64 `json:"rest_time"`
|
||||
}
|
||||
|
||||
// OtApplyInfo 以加班申请核算打卡记录相关信息
|
||||
type OtApplyInfo struct {
|
||||
AllowOtWorkingDay bool `json:"allow_ot_workingday"`
|
||||
AllowOtNonWorkingDay bool `json:"allow_ot_nonworkingday"`
|
||||
Uiptime int64 `json:"uptime"`
|
||||
OtNonworkingDaySpanDayTime int64 `json:"ot_nonworkingday_spanday_time"`
|
||||
OtWorkingDayRestInfo OtRestInfo `json:"ot_workingday_restinfo"`
|
||||
OtNonWorkingDayRestInfo OtRestInfo `json:"ot_nonworkingday_restinfo"`
|
||||
}
|
||||
|
||||
// ScheduleList 排班信息列表
|
||||
type ScheduleList struct {
|
||||
ScheduleID int64 `json:"schedule_id"`
|
||||
ScheduleName string `json:"schedule_name"`
|
||||
TimeSection []TimeSection `json:"time_section"`
|
||||
LimitAheadTime int64 `json:"limit_aheadtime"`
|
||||
NoNeedOffWork bool `json:"noneed_offwork"`
|
||||
LimitOffTime int64 `json:"limit_offtime"`
|
||||
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
|
||||
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
|
||||
AllowFlex bool `json:"allow_flex"`
|
||||
LateRule LateRule `json:"late_rule"`
|
||||
MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"`
|
||||
MaxAllowArriveLate int64 `json:"max_allow_arrive_late"`
|
||||
}
|
||||
|
||||
// TimeSection 班次上下班时段信息
|
||||
type TimeSection struct {
|
||||
TimeID int64 `json:"time_id"`
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
RestBeginTime int64 `json:"rest_begin_time"`
|
||||
RestEndTime int64 `json:"rest_end_time"`
|
||||
AllowRest bool `json:"allow_rest"`
|
||||
}
|
||||
|
||||
// LateRule 晚走晚到时间规则信息
|
||||
type LateRule struct {
|
||||
AllowOffWorkAfterTime bool `json:"allow_offwork_after_time"`
|
||||
TimeRules []TimeRule `json:"timerules"`
|
||||
}
|
||||
|
||||
// TimeRule 迟到规则时间
|
||||
type TimeRule struct {
|
||||
OffWorkAfterTime int64 `json:"offwork_after_time"`
|
||||
OnWorkFlexTime int64 `json:"onwork_flex_time"`
|
||||
}
|
||||
|
||||
// GetCorpOption 获取企业所有打卡规则
|
||||
// @see https://developer.work.weixin.qq.com/document/path/93384
|
||||
func (r *Client) GetCorpOption() (*GetCorpOptionResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPPost(fmt.Sprintf(getCorpOptionURL, accessToken), ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCorpOptionResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCorpOption")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetOptionRequest 获取员工打卡规则请求
|
||||
type GetOptionRequest struct {
|
||||
Datetime int64 `json:"datetime"`
|
||||
UserIDList []string `json:"useridlist"`
|
||||
}
|
||||
|
||||
// GetOptionResponse 获取员工打卡规则响应
|
||||
type GetOptionResponse struct {
|
||||
util.CommonError
|
||||
Info []OptionInfo `json:"info"`
|
||||
}
|
||||
|
||||
// OptionInfo 打卡规则列表
|
||||
type OptionInfo struct {
|
||||
UserID string `json:"userid"`
|
||||
Group OptionGroup `json:"group"`
|
||||
}
|
||||
|
||||
// OptionGroup 打卡规则相关信息
|
||||
type OptionGroup struct {
|
||||
GroupType int64 `json:"grouptype"`
|
||||
GroupID int64 `json:"groupid"`
|
||||
GroupName string `json:"groupname"`
|
||||
CheckinDate []OptionCheckinDate `json:"checkindate"`
|
||||
SpeWorkdays []SpeWorkdays `json:"spe_workdays"`
|
||||
SpeOffDays []SpeOffDays `json:"spe_offdays"`
|
||||
SyncHolidays bool `json:"sync_holidays"`
|
||||
NeedPhoto bool `json:"need_photo"`
|
||||
WifiMacInfos []WifiMacInfos `json:"wifimac_infos"`
|
||||
NoteCanUseLocalPic bool `json:"note_can_use_local_pic"`
|
||||
AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday"`
|
||||
AllowApplyOffWorkday bool `json:"allow_apply_offworkday"`
|
||||
LocInfos []LocInfos `json:"loc_infos"`
|
||||
ScheduleList []ScheduleList `json:"schedulelist"`
|
||||
BukaRestriction int64 `json:"buka_restriction"`
|
||||
}
|
||||
|
||||
// OptionCheckinDate 打卡时间配置
|
||||
type OptionCheckinDate struct {
|
||||
Workdays []int64 `json:"workdays"`
|
||||
CheckinTime []GroupCheckinTime `json:"checkintime"`
|
||||
FlexTime int64 `json:"flex_time"`
|
||||
NoNeedOffWork bool `json:"noneed_offwork"`
|
||||
LimitAheadTime int64 `json:"limit_aheadtime"`
|
||||
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
|
||||
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
|
||||
}
|
||||
|
||||
// GetOption 获取员工打卡规则
|
||||
// see https://developer.work.weixin.qq.com/document/path/90263
|
||||
func (r *Client) GetOption(req *GetOptionRequest) (*GetOptionResponse, 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(getOptionURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetOptionResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetOption")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetScheduleListRequest 获取打卡人员排班信息请求
|
||||
type GetScheduleListRequest struct {
|
||||
StartTime int64 `json:"starttime"`
|
||||
EndTime int64 `json:"endtime"`
|
||||
UserIDList []string `json:"useridlist"`
|
||||
}
|
||||
|
||||
// GetScheduleListResponse 获取打卡人员排班信息响应
|
||||
type GetScheduleListResponse struct {
|
||||
util.CommonError
|
||||
ScheduleList []ScheduleItem `json:"schedule_list"`
|
||||
}
|
||||
|
||||
// ScheduleItem 排班表信息
|
||||
type ScheduleItem struct {
|
||||
UserID string `json:"userid"`
|
||||
YearMonth int64 `json:"yearmonth"`
|
||||
GroupID int64 `json:"groupid"`
|
||||
GroupName string `json:"groupname"`
|
||||
Schedule Schedule `json:"schedule"`
|
||||
}
|
||||
|
||||
// Schedule 个人排班信息
|
||||
type Schedule struct {
|
||||
ScheduleList []ScheduleListItem `json:"scheduleList"`
|
||||
}
|
||||
|
||||
// ScheduleListItem 个人排班表信息
|
||||
type ScheduleListItem struct {
|
||||
Day int64 `json:"day"`
|
||||
ScheduleInfo ScheduleInfo `json:"schedule_info"`
|
||||
}
|
||||
|
||||
// ScheduleInfo 个人当日排班信息
|
||||
type ScheduleInfo struct {
|
||||
ScheduleID int64 `json:"schedule_id"`
|
||||
ScheduleName string `json:"schedule_name"`
|
||||
TimeSection []ScheduleTimeSection `json:"time_section"`
|
||||
}
|
||||
|
||||
// ScheduleTimeSection 班次上下班时段信息
|
||||
type ScheduleTimeSection struct {
|
||||
ID int64 `json:"id"`
|
||||
WorkSec int64 `json:"work_sec"`
|
||||
OffWorkSec int64 `json:"off_work_sec"`
|
||||
RemindWorkSec int64 `json:"remind_work_sec"`
|
||||
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
|
||||
}
|
||||
|
||||
// GetScheduleList 获取打卡人员排班信息
|
||||
// see https://developer.work.weixin.qq.com/document/path/93380
|
||||
func (r *Client) GetScheduleList(req *GetScheduleListRequest) (*GetScheduleListResponse, 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(getScheduleListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetScheduleListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetScheduleList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetHardwareDataRequest 获取设备打卡数据请求
|
||||
type GetHardwareDataRequest struct {
|
||||
FilterType int64 `json:"filter_type"`
|
||||
StartTime int64 `json:"starttime"`
|
||||
EndTime int64 `json:"endtime"`
|
||||
UserIDList []string `json:"useridlist"`
|
||||
}
|
||||
|
||||
// GetHardwareDataResponse 获取设备打卡数据响应
|
||||
type GetHardwareDataResponse struct {
|
||||
util.CommonError
|
||||
CheckinData []HardwareCheckinData `json:"checkindata"`
|
||||
}
|
||||
|
||||
// HardwareCheckinData 设备打卡数据
|
||||
type HardwareCheckinData struct {
|
||||
UserID string `json:"userid"`
|
||||
CheckinTime int64 `json:"checkin_time"`
|
||||
DeviceSn string `json:"device_sn"`
|
||||
DeviceName string `json:"device_name"`
|
||||
}
|
||||
|
||||
// GetHardwareData 获取设备打卡数据
|
||||
// see https://developer.work.weixin.qq.com/document/path/94126
|
||||
func (r *Client) GetHardwareData(req *GetHardwareDataRequest) (*GetHardwareDataResponse, 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(getHardwareDataURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetHardwareDataResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetHardwareData")
|
||||
return result, err
|
||||
}
|
||||
@@ -38,8 +38,6 @@ func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg EventCallbackMessa
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = xml.Unmarshal(bData, &msg); err != nil {
|
||||
return
|
||||
}
|
||||
err = xml.Unmarshal(bData, &msg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// AddContactWayURL 配置客户联系「联系我」方式
|
||||
AddContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=%s"
|
||||
// GetContactWayURL 获取企业已配置的「联系我」方式
|
||||
GetContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=%s"
|
||||
// UpdateContactWayURL 更新企业已配置的「联系我」方式
|
||||
UpdateContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=%s"
|
||||
// ListContactWayURL 获取企业已配置的「联系我」列表
|
||||
ListContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=%s"
|
||||
// DelContactWayURL 删除企业已配置的「联系我」方式
|
||||
DelContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=%s"
|
||||
// addContactWayURL 配置客户联系「联系我」方式
|
||||
addContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=%s"
|
||||
// getContactWayURL 获取企业已配置的「联系我」方式
|
||||
getContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=%s"
|
||||
// updateContactWayURL 更新企业已配置的「联系我」方式
|
||||
updateContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=%s"
|
||||
// listContactWayURL 获取企业已配置的「联系我」列表
|
||||
listContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=%s"
|
||||
// delContactWayURL 删除企业已配置的「联系我」方式
|
||||
delContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -98,14 +98,12 @@ func (r *Client) AddContactWay(req *AddContactWayRequest) (*AddContactWayRespons
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddContactWayURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(addContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "AddContactWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -149,14 +147,12 @@ func (r *Client) GetContactWay(req *GetContactWayRequest) (*GetContactWayRespons
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetContactWayURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetContactWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -191,14 +187,12 @@ func (r *Client) UpdateContactWay(req *UpdateContactWayRequest) (*UpdateContactW
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(UpdateContactWayURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(updateContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UpdateContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "UpdateContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "UpdateContactWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -232,14 +226,12 @@ func (r *Client) ListContactWay(req *ListContactWayRequest) (*ListContactWayResp
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(ListContactWayURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(listContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "ListContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "ListContactWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -264,12 +256,10 @@ func (r *Client) DelContactWay(req *DelContactWayRequest) (*DelContactWayRespons
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(DelContactWayURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(delContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DelContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "DelContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "DelContactWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
310
work/externalcontact/customer_acquisition.go
Normal file
310
work/externalcontact/customer_acquisition.go
Normal file
@@ -0,0 +1,310 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// listLinkUrl 获取获客链接列表
|
||||
listLinkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/list_link?access_token=%s"
|
||||
// getCustomerAcquisition 获取获客链接详情
|
||||
getCustomerAcquisitionURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/get?access_token=%s"
|
||||
// createCustomerAcquisitionLink 创建获客链接
|
||||
createCustomerAcquisitionLinkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/create_link?access_token=%s"
|
||||
// updateCustomerAcquisitionLink 编辑获客链接
|
||||
updateCustomerAcquisitionLinkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/update_link?access_token=%s"
|
||||
// deleteCustomerAcquisitionLink 删除获客链接
|
||||
deleteCustomerAcquisitionLinkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/delete_link?access_token=%s"
|
||||
// getCustomerInfoWithCustomerAcquisitionLinkURL 获取由获客链接添加的客户信息
|
||||
getCustomerInfoWithCustomerAcquisitionLinkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/customer?access_token=%s"
|
||||
// customerAcquisitionQuota 查询剩余使用量
|
||||
customerAcquisitionQuotaURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition_quota?access_token=%s"
|
||||
// customerAcquisitionStatistic 查询链接使用详情
|
||||
customerAcquisitionStatisticURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/statistic?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
// ListLinkRequest 获取获客链接列表请求
|
||||
ListLinkRequest struct {
|
||||
Limit int `json:"limit"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
// ListLinkResponse 获取获客链接列表响应
|
||||
ListLinkResponse struct {
|
||||
util.CommonError
|
||||
LinkIDList []string `json:"link_id_list"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
)
|
||||
|
||||
// ListLink 获客助手--获取获客链接列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/97297
|
||||
func (r *Client) ListLink(req *ListLinkRequest) (*ListLinkResponse, 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(listLinkURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListLinkResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListLink")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// GetCustomerAcquisitionRequest 获取获客链接详情请求
|
||||
GetCustomerAcquisitionRequest struct {
|
||||
LinkID string `json:"link_id"`
|
||||
}
|
||||
// GetCustomerAcquisitionResponse 获取获客链接详情响应
|
||||
GetCustomerAcquisitionResponse struct {
|
||||
util.CommonError
|
||||
Link Link `json:"link"`
|
||||
Range CustomerAcquisitionRange `json:"range"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
}
|
||||
// Link 获客链接
|
||||
Link struct {
|
||||
LinkID string `json:"link_id"`
|
||||
LinkName string `json:"link_name"`
|
||||
URL string `json:"url"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
}
|
||||
|
||||
// CustomerAcquisitionRange 该获客链接使用范围
|
||||
CustomerAcquisitionRange struct {
|
||||
UserList []string `json:"user_list"`
|
||||
DepartmentList []int64 `json:"department_list"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetCustomerAcquisition 获客助手--获取获客链接详情
|
||||
// see https://developer.work.weixin.qq.com/document/path/97297
|
||||
func (r *Client) GetCustomerAcquisition(req *GetCustomerAcquisitionRequest) (*GetCustomerAcquisitionResponse, 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(getCustomerAcquisitionURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCustomerAcquisitionResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCustomerAcquisition")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// CreateCustomerAcquisitionLinkRequest 创建获客链接请求
|
||||
CreateCustomerAcquisitionLinkRequest struct {
|
||||
LinkName string `json:"link_name"`
|
||||
Range CustomerAcquisitionRange `json:"range"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
}
|
||||
// CreateCustomerAcquisitionLinkResponse 创建获客链接响应
|
||||
CreateCustomerAcquisitionLinkResponse struct {
|
||||
util.CommonError
|
||||
Link Link `json:"link"`
|
||||
}
|
||||
)
|
||||
|
||||
// CreateCustomerAcquisitionLink 获客助手--创建获客链接
|
||||
// see https://developer.work.weixin.qq.com/document/path/97297
|
||||
func (r *Client) CreateCustomerAcquisitionLink(req *CreateCustomerAcquisitionLinkRequest) (*CreateCustomerAcquisitionLinkResponse, 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(createCustomerAcquisitionLinkURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CreateCustomerAcquisitionLinkResponse{}
|
||||
err = util.DecodeWithError(response, result, "CreateCustomerAcquisitionLink")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// UpdateCustomerAcquisitionLinkRequest 编辑获客链接请求
|
||||
UpdateCustomerAcquisitionLinkRequest struct {
|
||||
LinkID string `json:"link_id"`
|
||||
LinkName string `json:"link_name"`
|
||||
Range CustomerAcquisitionRange `json:"range"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
}
|
||||
// UpdateCustomerAcquisitionLinkResponse 编辑获客链接响应
|
||||
UpdateCustomerAcquisitionLinkResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// UpdateCustomerAcquisitionLink 获客助手--编辑获客链接
|
||||
// see https://developer.work.weixin.qq.com/document/path/97297
|
||||
func (r *Client) UpdateCustomerAcquisitionLink(req *UpdateCustomerAcquisitionLinkRequest) (*UpdateCustomerAcquisitionLinkResponse, 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(updateCustomerAcquisitionLinkURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UpdateCustomerAcquisitionLinkResponse{}
|
||||
err = util.DecodeWithError(response, result, "UpdateCustomerAcquisitionLink")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// DeleteCustomerAcquisitionLinkRequest 删除获客链接请求
|
||||
DeleteCustomerAcquisitionLinkRequest struct {
|
||||
LinkID string `json:"link_id"`
|
||||
}
|
||||
// DeleteCustomerAcquisitionLinkResponse 删除获客链接响应
|
||||
DeleteCustomerAcquisitionLinkResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// DeleteCustomerAcquisitionLink 获客助手--删除获客链接
|
||||
// see https://developer.work.weixin.qq.com/document/path/97297
|
||||
func (r *Client) DeleteCustomerAcquisitionLink(req *DeleteCustomerAcquisitionLinkRequest) (*DeleteCustomerAcquisitionLinkResponse, 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(deleteCustomerAcquisitionLinkURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DeleteCustomerAcquisitionLinkResponse{}
|
||||
err = util.DecodeWithError(response, result, "DeleteCustomerAcquisitionLink")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// GetCustomerInfoWithCustomerAcquisitionLinkRequest 获取由获客链接添加的客户信息请求
|
||||
GetCustomerInfoWithCustomerAcquisitionLinkRequest struct {
|
||||
LinkID string `json:"link_id"`
|
||||
Limit int64 `json:"limit"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
// GetCustomerInfoWithCustomerAcquisitionLinkResponse 获取由获客链接添加的客户信息响应
|
||||
GetCustomerInfoWithCustomerAcquisitionLinkResponse struct {
|
||||
util.CommonError
|
||||
CustomerList []CustomerList `json:"customer_list"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
// CustomerList 客户列表
|
||||
CustomerList struct {
|
||||
ExternalUserid string `json:"external_userid"`
|
||||
Userid string `json:"userid"`
|
||||
ChatStatus int64 `json:"chat_status"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetCustomerInfoWithCustomerAcquisitionLink 获客助手--获取由获客链接添加的客户信息
|
||||
// see https://developer.work.weixin.qq.com/document/path/97298
|
||||
func (r *Client) GetCustomerInfoWithCustomerAcquisitionLink(req *GetCustomerInfoWithCustomerAcquisitionLinkRequest) (*GetCustomerInfoWithCustomerAcquisitionLinkResponse, 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(getCustomerInfoWithCustomerAcquisitionLinkURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCustomerInfoWithCustomerAcquisitionLinkResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCustomerInfoWithCustomerAcquisitionLink")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// CustomerAcquisitionQuotaResponse 查询剩余使用量响应
|
||||
CustomerAcquisitionQuotaResponse struct {
|
||||
util.CommonError
|
||||
Total int64 `json:"total"`
|
||||
Balance int64 `json:"balance"`
|
||||
QuotaList []QuotaList `json:"quota_list"`
|
||||
}
|
||||
// QuotaList 额度
|
||||
QuotaList struct {
|
||||
ExpireDate int64 `json:"expire_date"`
|
||||
Balance int64 `json:"balance"`
|
||||
}
|
||||
)
|
||||
|
||||
// CustomerAcquisitionQuota 获客助手额度管理与使用统计--查询剩余使用量
|
||||
// see https://developer.work.weixin.qq.com/document/path/97375
|
||||
func (r *Client) CustomerAcquisitionQuota() (*CustomerAcquisitionQuotaResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(customerAcquisitionQuotaURL, accessToken)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CustomerAcquisitionQuotaResponse{}
|
||||
err = util.DecodeWithError(response, result, "CustomerAcquisitionQuota")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
// CustomerAcquisitionStatisticRequest 查询链接使用详情请求
|
||||
CustomerAcquisitionStatisticRequest struct {
|
||||
LinkID string `json:"link_id"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
}
|
||||
// CustomerAcquisitionStatisticResponse 查询链接使用详情响应
|
||||
CustomerAcquisitionStatisticResponse struct {
|
||||
util.CommonError
|
||||
ClickLinkCustomerCnt int64 `json:"click_link_customer_cnt"`
|
||||
NewCustomerCnt int64 `json:"new_customer_cnt"`
|
||||
}
|
||||
)
|
||||
|
||||
// CustomerAcquisitionStatistic 获客助手额度管理与使用统计--查询链接使用详情
|
||||
// see https://developer.work.weixin.qq.com/document/path/97375
|
||||
func (r *Client) CustomerAcquisitionStatistic(req *CustomerAcquisitionStatisticRequest) (*CustomerAcquisitionStatisticResponse, 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(customerAcquisitionStatisticURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CustomerAcquisitionStatisticResponse{}
|
||||
err = util.DecodeWithError(response, result, "CustomerAcquisitionStatistic")
|
||||
return result, err
|
||||
}
|
||||
@@ -8,14 +8,26 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// FetchExternalContactUserListURL 获取客户列表
|
||||
FetchExternalContactUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"
|
||||
// FetchExternalContactUserDetailURL 获取客户详情
|
||||
FetchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
|
||||
// FetchBatchExternalContactUserDetailURL 批量获取客户详情
|
||||
FetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
|
||||
// UpdateUserRemarkURL 更新客户备注信息
|
||||
UpdateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark"
|
||||
// fetchExternalContactUserListURL 获取客户列表
|
||||
fetchExternalContactUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"
|
||||
// fetchExternalContactUserDetailURL 获取客户详情
|
||||
fetchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
|
||||
// fetchBatchExternalContactUserDetailURL 批量获取客户详情
|
||||
fetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
|
||||
// updateUserRemarkURL 更新客户备注信息
|
||||
updateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark"
|
||||
// listCustomerStrategyURL 获取规则组列表
|
||||
listCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/list?access_token=%s"
|
||||
// getCustomerStrategyURL 获取规则组详情
|
||||
getCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/get?access_token=%s"
|
||||
// getRangeCustomerStrategyURL 获取规则组管理范围
|
||||
getRangeCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/get_range?access_token=%s"
|
||||
// createCustomerStrategyURL 创建新的规则组
|
||||
createCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/create?access_token=%s"
|
||||
// editCustomerStrategyURL 编辑规则组及其管理范围
|
||||
editCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/edit?access_token=%s"
|
||||
// delCustomerStrategyURL 删除规则组
|
||||
delCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/del?access_token=%s"
|
||||
)
|
||||
|
||||
// ExternalUserListResponse 外部联系人列表响应
|
||||
@@ -32,16 +44,13 @@ func (r *Client) GetExternalUserList(userID string) ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&userid=%v", FetchExternalContactUserListURL, accessToken, userID))
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&userid=%v", fetchExternalContactUserListURL, accessToken, userID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ExternalUserListResponse
|
||||
err = util.DecodeWithError(response, &result, "GetExternalUserList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.ExternalUserID, nil
|
||||
return result.ExternalUserID, err
|
||||
}
|
||||
|
||||
// ExternalUserDetailResponse 外部联系人详情响应
|
||||
@@ -54,16 +63,16 @@ type ExternalUserDetailResponse struct {
|
||||
|
||||
// ExternalUser 外部联系人
|
||||
type ExternalUser struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Type int64 `json:"type"`
|
||||
Gender int64 `json:"gender"`
|
||||
UnionID string `json:"unionid"`
|
||||
Position string `json:"position"`
|
||||
CorpName string `json:"corp_name"`
|
||||
CorpFullName string `json:"corp_full_name"`
|
||||
ExternalProfile string `json:"external_profile"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Type int64 `json:"type"`
|
||||
Gender int64 `json:"gender"`
|
||||
UnionID string `json:"unionid"`
|
||||
Position string `json:"position"`
|
||||
CorpName string `json:"corp_name"`
|
||||
CorpFullName string `json:"corp_full_name"`
|
||||
ExternalProfile *ExternalProfile `json:"external_profile,omitempty"`
|
||||
}
|
||||
|
||||
// FollowUser 跟进用户(指企业内部用户)
|
||||
@@ -71,7 +80,7 @@ type FollowUser struct {
|
||||
UserID string `json:"userid"`
|
||||
Remark string `json:"remark"`
|
||||
Description string `json:"description"`
|
||||
CreateTime string `json:"create_time"`
|
||||
CreateTime int64 `json:"createtime"`
|
||||
Tags []Tag `json:"tags"`
|
||||
RemarkCorpName string `json:"remark_corp_name"`
|
||||
RemarkMobiles []string `json:"remark_mobiles"`
|
||||
@@ -92,7 +101,47 @@ type Tag struct {
|
||||
// WechatChannel 视频号添加的场景
|
||||
type WechatChannel struct {
|
||||
NickName string `json:"nickname"`
|
||||
Source string `json:"source"`
|
||||
Source int `json:"source"`
|
||||
}
|
||||
|
||||
// ExternalProfile 外部联系人的自定义展示信息,可以有多个字段和多种类型,包括文本,网页和小程序
|
||||
type ExternalProfile struct {
|
||||
ExternalCorpName string `json:"external_corp_name"`
|
||||
WechatChannels WechatChannels `json:"wechat_channels"`
|
||||
ExternalAttr []ExternalAttr `json:"external_attr"`
|
||||
}
|
||||
|
||||
// WechatChannels 视频号属性。须从企业绑定到企业微信的视频号中选择,可在“我的企业”页中查看绑定的视频号
|
||||
type WechatChannels struct {
|
||||
Nickname string `json:"nickname"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
// ExternalAttr 属性列表,目前支持文本、网页、小程序三种类型
|
||||
type ExternalAttr struct {
|
||||
Type int `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Text *Text `json:"text,omitempty"`
|
||||
Web *Web `json:"web,omitempty"`
|
||||
MiniProgram *MiniProgram `json:"miniprogram,omitempty"`
|
||||
}
|
||||
|
||||
// Text 文本
|
||||
type Text struct {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Web 网页
|
||||
type Web struct {
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
// MiniProgram 小程序
|
||||
type MiniProgram struct {
|
||||
AppID string `json:"appid"`
|
||||
Pagepath string `json:"pagepath"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
// GetExternalUserDetail 获取外部联系人详情
|
||||
@@ -107,22 +156,20 @@ func (r *Client) GetExternalUserDetail(externalUserID string, nextCursor ...stri
|
||||
if len(nextCursor) > 0 {
|
||||
cursor = nextCursor[0]
|
||||
}
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&external_userid=%v&cursor=%v", FetchExternalContactUserDetailURL, accessToken, externalUserID, cursor))
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&external_userid=%v&cursor=%v", fetchExternalContactUserDetailURL, accessToken, externalUserID, cursor))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ExternalUserDetailResponse{}
|
||||
err = util.DecodeWithError(response, result, "get_external_user_detail")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
return result, err
|
||||
}
|
||||
|
||||
// BatchGetExternalUserDetailsRequest 批量获取外部联系人详情请求
|
||||
type BatchGetExternalUserDetailsRequest struct {
|
||||
UserIDList []string `json:"userid_list"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// ExternalUserDetailListResponse 批量获取外部联系人详情响应
|
||||
@@ -156,7 +203,7 @@ type FollowInfo struct {
|
||||
UserID string `json:"userid"`
|
||||
Remark string `json:"remark"`
|
||||
Description string `json:"description"`
|
||||
CreateTime int `json:"create_time"`
|
||||
CreateTime int64 `json:"createtime"`
|
||||
TagID []string `json:"tag_id"`
|
||||
RemarkCorpName string `json:"remark_corp_name"`
|
||||
RemarkMobiles []string `json:"remark_mobiles"`
|
||||
@@ -177,16 +224,13 @@ func (r *Client) BatchGetExternalUserDetails(request BatchGetExternalUserDetails
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", FetchBatchExternalContactUserDetailURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", fetchBatchExternalContactUserDetailURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ExternalUserDetailListResponse
|
||||
err = util.DecodeWithError(response, &result, "BatchGetExternalUserDetails")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.ExternalContactList, nil
|
||||
return result.ExternalContactList, err
|
||||
}
|
||||
|
||||
// UpdateUserRemarkRequest 修改客户备注信息请求体
|
||||
@@ -212,9 +256,234 @@ func (r *Client) UpdateUserRemark(request UpdateUserRemarkRequest) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", UpdateUserRemarkURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", updateUserRemarkURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateUserRemark")
|
||||
}
|
||||
|
||||
// ListCustomerStrategyRequest 获取规则组列表请求
|
||||
type ListCustomerStrategyRequest struct {
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// ListCustomerStrategyResponse 获取规则组列表响应
|
||||
type ListCustomerStrategyResponse struct {
|
||||
util.CommonError
|
||||
Strategy []StrategyID `json:"strategy"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// StrategyID 规则组ID
|
||||
type StrategyID struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// ListCustomerStrategy 获取规则组列表
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8
|
||||
func (r *Client) ListCustomerStrategy(req *ListCustomerStrategyRequest) (*ListCustomerStrategyResponse, 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(listCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListCustomerStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListCustomerStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetCustomerStrategyRequest 获取规则组详情请求
|
||||
type GetCustomerStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// GetCustomerStrategyResponse 获取规则组详情响应
|
||||
type GetCustomerStrategyResponse struct {
|
||||
util.CommonError
|
||||
Strategy Strategy `json:"strategy"`
|
||||
}
|
||||
|
||||
// Strategy 规则组
|
||||
type Strategy struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
ParentID int `json:"parent_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
}
|
||||
|
||||
// Privilege 权限
|
||||
type Privilege struct {
|
||||
ViewCustomerList bool `json:"view_customer_list"`
|
||||
ViewCustomerData bool `json:"view_customer_data"`
|
||||
ViewRoomList bool `json:"view_room_list"`
|
||||
ContactMe bool `json:"contact_me"`
|
||||
JoinRoom bool `json:"join_room"`
|
||||
ShareCustomer bool `json:"share_customer"`
|
||||
OperResignCustomer bool `json:"oper_resign_customer"`
|
||||
OperResignGroup bool `json:"oper_resign_group"`
|
||||
SendCustomerMsg bool `json:"send_customer_msg"`
|
||||
EditWelcomeMsg bool `json:"edit_welcome_msg"`
|
||||
ViewBehaviorData bool `json:"view_behavior_data"`
|
||||
ViewRoomData bool `json:"view_room_data"`
|
||||
SendGroupMsg bool `json:"send_group_msg"`
|
||||
RoomDeduplication bool `json:"room_deduplication"`
|
||||
RapidReply bool `json:"rapid_reply"`
|
||||
OnjobCustomerTransfer bool `json:"onjob_customer_transfer"`
|
||||
EditAntiSpamRule bool `json:"edit_anti_spam_rule"`
|
||||
ExportCustomerList bool `json:"export_customer_list"`
|
||||
ExportCustomerData bool `json:"export_customer_data"`
|
||||
ExportCustomerGroupList bool `json:"export_customer_group_list"`
|
||||
ManageCustomerTag bool `json:"manage_customer_tag"`
|
||||
}
|
||||
|
||||
// GetCustomerStrategy 获取规则组详情
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85
|
||||
func (r *Client) GetCustomerStrategy(req *GetCustomerStrategyRequest) (*GetCustomerStrategyResponse, 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(getCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCustomerStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCustomerStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetRangeCustomerStrategyRequest 获取规则组管理范围请求
|
||||
type GetRangeCustomerStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetRangeCustomerStrategyResponse 获取规则组管理范围响应
|
||||
type GetRangeCustomerStrategyResponse struct {
|
||||
util.CommonError
|
||||
Range []Range `json:"range"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// Range 管理范围节点
|
||||
type Range struct {
|
||||
Type int `json:"type"`
|
||||
UserID string `json:"userid,omitempty"`
|
||||
PartyID int `json:"partyid,omitempty"`
|
||||
}
|
||||
|
||||
// GetRangeCustomerStrategy 获取规则组管理范围
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
|
||||
func (r *Client) GetRangeCustomerStrategy(req *GetRangeCustomerStrategyRequest) (*GetRangeCustomerStrategyResponse, 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(getRangeCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetRangeCustomerStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetRangeCustomerStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// CreateCustomerStrategyRequest 创建新的规则组请求
|
||||
type CreateCustomerStrategyRequest struct {
|
||||
ParentID int `json:"parent_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
Range []Range `json:"range"`
|
||||
}
|
||||
|
||||
// CreateCustomerStrategyResponse 创建新的规则组响应
|
||||
type CreateCustomerStrategyResponse struct {
|
||||
util.CommonError
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// CreateCustomerStrategy 创建新的规则组
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84
|
||||
func (r *Client) CreateCustomerStrategy(req *CreateCustomerStrategyRequest) (*CreateCustomerStrategyResponse, 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(createCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CreateCustomerStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "CreateCustomerStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// EditCustomerStrategyRequest 编辑规则组及其管理范围请求
|
||||
type EditCustomerStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege Privilege `json:"privilege"`
|
||||
RangeAdd []Range `json:"range_add"`
|
||||
RangeDel []Range `json:"range_del"`
|
||||
}
|
||||
|
||||
// EditCustomerStrategy 编辑规则组及其管理范围
|
||||
// see https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
|
||||
func (r *Client) EditCustomerStrategy(req *EditCustomerStrategyRequest) 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(editCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "EditCustomerStrategy")
|
||||
}
|
||||
|
||||
// DelCustomerStrategyRequest 删除规则组请求
|
||||
type DelCustomerStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// DelCustomerStrategy 删除规则组
|
||||
// see https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84
|
||||
func (r *Client) DelCustomerStrategy(req *DelCustomerStrategyRequest) 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(delCustomerStrategyURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelCustomerStrategy")
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// FetchFollowUserListURL 获取配置了客户联系功能的成员列表
|
||||
FetchFollowUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list"
|
||||
// fetchFollowUserListURL 获取配置了客户联系功能的成员列表
|
||||
fetchFollowUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list"
|
||||
)
|
||||
|
||||
// followerUserResponse 客户联系功能的成员列表响应
|
||||
@@ -25,14 +25,11 @@ func (r *Client) GetFollowUserList() ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%s", FetchFollowUserListURL, accessToken))
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%s", fetchFollowUserListURL, accessToken))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result followerUserResponse
|
||||
err = util.DecodeWithError(response, &result, "GetFollowUserList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.FollowUser, nil
|
||||
return result.FollowUser, err
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// OpengIDToChatIDURL 客户群opengid转换URL
|
||||
const OpengIDToChatIDURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/opengid_to_chatid"
|
||||
// opengIDToChatIDURL 客户群opengid转换URL
|
||||
const opengIDToChatIDURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/opengid_to_chatid"
|
||||
|
||||
type (
|
||||
//GroupChatListRequest 获取客户群列表的请求参数
|
||||
@@ -39,15 +39,13 @@ func (r *Client) GetGroupChatList(req *GroupChatListRequest) (*GroupChatListResp
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/list?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/list?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatListResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatList"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetGroupChatList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -70,6 +68,7 @@ type (
|
||||
GroupNickname string `json:"group_nickname"` //在群里的昵称
|
||||
Name string `json:"name"` //名字。仅当 need_name = 1 时返回 如果是微信用户,则返回其在微信中设置的名字 如果是企业微信联系人,则返回其设置对外展示的别名或实名
|
||||
UnionID string `json:"unionid,omitempty"` //外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。仅当群成员类型是微信用户(包括企业成员未添加好友),且企业绑定了微信开发者ID有此字段(查看绑定方法)。第三方不可获取,上游企业不可获取下游企业客户的unionid字段
|
||||
State string `json:"state,omitempty"` //如果在配置入群方式时,配置了state参数,那么在获取客户群详情时,通过该方式入群的成员,会额外获取到相应的state参数
|
||||
}
|
||||
//GroupChatAdmin 群管理员
|
||||
GroupChatAdmin struct {
|
||||
@@ -77,13 +76,14 @@ type (
|
||||
}
|
||||
//GroupChat 客户群详情
|
||||
GroupChat struct {
|
||||
ChatID string `json:"chat_id"` //客户群ID
|
||||
Name string `json:"name"` //群名
|
||||
Owner string `json:"owner"` //群主ID
|
||||
CreateTime int `json:"create_time"` //群的创建时间
|
||||
Notice string `json:"notice"` //群公告
|
||||
MemberList []GroupChatMember `json:"member_list"` //群成员列表
|
||||
AdminList []GroupChatAdmin `json:"admin_list"` //群管理员列表
|
||||
ChatID string `json:"chat_id"` //客户群ID
|
||||
Name string `json:"name"` //群名
|
||||
Owner string `json:"owner"` //群主ID
|
||||
CreateTime int64 `json:"create_time"` //群的创建时间
|
||||
Notice string `json:"notice"` //群公告
|
||||
MemberList []GroupChatMember `json:"member_list"` //群成员列表
|
||||
AdminList []GroupChatAdmin `json:"admin_list"` //群管理员列表
|
||||
MemberVersion string `json:"member_version"` //当前群成员版本号。可以配合客户群变更事件减少主动调用本接口的次数
|
||||
}
|
||||
//GroupChatDetailResponse 客户群详情 返回值
|
||||
GroupChatDetailResponse struct {
|
||||
@@ -100,15 +100,13 @@ func (r *Client) GetGroupChatDetail(req *GroupChatDetailRequest) (*GroupChatDeta
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatDetailResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetGroupChatDetail")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -131,13 +129,11 @@ func (r *Client) OpengIDToChatID(req *OpengIDToChatIDRequest) (*OpengIDToChatIDR
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s?access_token=%s", OpengIDToChatIDURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s?access_token=%s", opengIDToChatIDURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &OpengIDToChatIDResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetGroupChatDetail")
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// GroupChatURL 客户群
|
||||
const GroupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat"
|
||||
// groupChatURL 客户群
|
||||
const groupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat"
|
||||
|
||||
type (
|
||||
// AddJoinWayRequest 添加群配置请求参数
|
||||
@@ -39,15 +39,13 @@ func (r *Client) AddJoinWay(req *AddJoinWayRequest) (*AddJoinWayResponse, error)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/add_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/add_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddJoinWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddJoinWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "AddJoinWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -86,15 +84,13 @@ func (r *Client) GetJoinWay(req *JoinWayConfigRequest) (*GetJoinWayResponse, err
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetJoinWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetJoinWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetJoinWay")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UpdateJoinWayRequest 更新群配置的请求参数
|
||||
@@ -120,7 +116,7 @@ func (r *Client) UpdateJoinWay(req *UpdateJoinWayRequest) error {
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/update_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/update_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -138,7 +134,7 @@ func (r *Client) DelJoinWay(req *JoinWayConfigRequest) error {
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/del_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/del_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
636
work/externalcontact/moment.go
Normal file
636
work/externalcontact/moment.go
Normal file
@@ -0,0 +1,636 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// addMomentTaskURL 创建发表任务
|
||||
addMomentTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_moment_task?access_token=%s"
|
||||
// getMomentTaskResultURL 获取任务创建结果
|
||||
getMomentTaskResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_task_result?access_token=%s&jobid=%s"
|
||||
// cancelMomentTaskURL 停止发表企业朋友圈
|
||||
cancelMomentTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/cancel_moment_task?access_token=%s"
|
||||
// getMomentListURL 获取企业全部的发表列表
|
||||
getMomentListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_list?access_token=%s"
|
||||
// getMomentTaskURL 获取客户朋友圈企业发表的列表
|
||||
getMomentTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_task?access_token=%s"
|
||||
// getMomentCustomerListURL 获取客户朋友圈发表时选择的可见范围
|
||||
getMomentCustomerListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_customer_list?access_token=%s"
|
||||
// getMomentSendResultURL 获取客户朋友圈发表后的可见客户列表
|
||||
getMomentSendResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_send_result?access_token=%s"
|
||||
// getMomentCommentsURL 获取客户朋友圈的互动数据
|
||||
getMomentCommentsURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_moment_comments?access_token=%s"
|
||||
// listMomentStrategyURL 获取规则组列表
|
||||
listMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/list?access_token=%s"
|
||||
// getMomentStrategyURL 获取规则组详情
|
||||
getMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/get?access_token=%s"
|
||||
// getRangeMomentStrategyURL 获取规则组管理范围
|
||||
getRangeMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/get_range?access_token=%s"
|
||||
// createMomentStrategyURL 创建新的规则组
|
||||
createMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/create?access_token=%s"
|
||||
// editMomentStrategyURL 编辑规则组及其管理范围
|
||||
editMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/edit?access_token=%s"
|
||||
// delMomentStrategyURL 删除规则组
|
||||
delMomentStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/moment_strategy/del?access_token=%s"
|
||||
)
|
||||
|
||||
// AddMomentTaskRequest 创建发表任务请求
|
||||
type AddMomentTaskRequest struct {
|
||||
Text MomentTaskText `json:"text"`
|
||||
Attachments []MomentTaskAttachment `json:"attachments"`
|
||||
VisibleRange MomentVisibleRange `json:"visible_range"`
|
||||
}
|
||||
|
||||
// MomentTaskText 发表任务文本消息
|
||||
type MomentTaskText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// MomentTaskImage 发表任务图片消息
|
||||
type MomentTaskImage struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// MomentTaskVideo 发表任务视频消息
|
||||
type MomentTaskVideo struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// MomentTaskLink 发表任务图文消息
|
||||
type MomentTaskLink struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// MomentTaskAttachment 发表任务附件
|
||||
type MomentTaskAttachment struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
Image MomentTaskImage `json:"image,omitempty"`
|
||||
Video MomentTaskVideo `json:"video,omitempty"`
|
||||
Link MomentTaskLink `json:"link,omitempty"`
|
||||
}
|
||||
|
||||
// MomentVisibleRange 朋友圈指定的发表范围
|
||||
type MomentVisibleRange struct {
|
||||
SenderList MomentSenderList `json:"sender_list"`
|
||||
ExternalContactList MomentExternalContactList `json:"external_contact_list"`
|
||||
}
|
||||
|
||||
// MomentSenderList 发表任务的执行者列表
|
||||
type MomentSenderList struct {
|
||||
UserList []string `json:"user_list"`
|
||||
DepartmentList []int `json:"department_list"`
|
||||
}
|
||||
|
||||
// MomentExternalContactList 可见到该朋友圈的客户列表
|
||||
type MomentExternalContactList struct {
|
||||
TagList []string `json:"tag_list"`
|
||||
}
|
||||
|
||||
// AddMomentTaskResponse 创建发表任务响应
|
||||
type AddMomentTaskResponse struct {
|
||||
util.CommonError
|
||||
JobID string `json:"jobid"`
|
||||
}
|
||||
|
||||
// AddMomentTask 创建发表任务
|
||||
// see https://developer.work.weixin.qq.com/document/path/95094#%E5%88%9B%E5%BB%BA%E5%8F%91%E8%A1%A8%E4%BB%BB%E5%8A%A1
|
||||
func (r *Client) AddMomentTask(req *AddMomentTaskRequest) (*AddMomentTaskResponse, 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(addMomentTaskURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddMomentTaskResponse{}
|
||||
err = util.DecodeWithError(response, result, "AddMomentTask")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentTaskResultResponse 获取任务创建结果响应
|
||||
type GetMomentTaskResultResponse struct {
|
||||
util.CommonError
|
||||
Status int `json:"status"`
|
||||
Type string `json:"type"`
|
||||
Result MomentTaskResult `json:"result"`
|
||||
}
|
||||
|
||||
// MomentTaskResult 任务创建结果
|
||||
type MomentTaskResult struct {
|
||||
ErrCode int64 `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
MomentID string `json:"moment_id"`
|
||||
InvalidSenderList MomentInvalidSenderList `json:"invalid_sender_list"`
|
||||
InvalidExternalContactList MomentInvalidExternalContactList `json:"invalid_external_contact_list"`
|
||||
}
|
||||
|
||||
// MomentInvalidSenderList 不合法的执行者列表
|
||||
type MomentInvalidSenderList struct {
|
||||
UserList []string `json:"user_list"`
|
||||
DepartmentList []int `json:"department_list"`
|
||||
}
|
||||
|
||||
// MomentInvalidExternalContactList 不合法的可见到该朋友圈的客户列表
|
||||
type MomentInvalidExternalContactList struct {
|
||||
TagList []string `json:"tag_list"`
|
||||
}
|
||||
|
||||
// GetMomentTaskResult 获取任务创建结果
|
||||
// see https://developer.work.weixin.qq.com/document/path/95094#%E8%8E%B7%E5%8F%96%E4%BB%BB%E5%8A%A1%E5%88%9B%E5%BB%BA%E7%BB%93%E6%9E%9C
|
||||
func (r *Client) GetMomentTaskResult(jobID string) (*GetMomentTaskResultResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(getMomentTaskResultURL, accessToken, jobID)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentTaskResultResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentTaskResult")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// CancelMomentTaskRequest 停止发表企业朋友圈请求
|
||||
type CancelMomentTaskRequest struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
}
|
||||
|
||||
// CancelMomentTask 停止发表企业朋友圈
|
||||
// see https://developer.work.weixin.qq.com/document/path/97612
|
||||
func (r *Client) CancelMomentTask(req *CancelMomentTaskRequest) 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(cancelMomentTaskURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "CancelMomentTask")
|
||||
}
|
||||
|
||||
// GetMomentListRequest 获取企业全部的发表列表请求
|
||||
type GetMomentListRequest struct {
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
Creator string `json:"creator"`
|
||||
FilterType int `json:"filter_type"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetMomentListResponse 获取企业全部的发表列表响应
|
||||
type GetMomentListResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
MomentList []MomentItem `json:"moment_list"`
|
||||
}
|
||||
|
||||
// MomentItem 朋友圈
|
||||
type MomentItem struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
CreateType int `json:"create_type"`
|
||||
VisibleType int `json:"visible_type"`
|
||||
Text MomentText `json:"text"`
|
||||
Image []MomentImage `json:"image"`
|
||||
Video MomentVideo `json:"video"`
|
||||
Link MomentLink `json:"link"`
|
||||
Location MomentLocation `json:"location"`
|
||||
}
|
||||
|
||||
// MomentText 朋友圈文本消息
|
||||
type MomentText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// MomentImage 朋友圈图片
|
||||
type MomentImage struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// MomentVideo 朋友圈视频
|
||||
type MomentVideo struct {
|
||||
MediaID string `json:"media_id"`
|
||||
ThumbMediaID string `json:"thumb_media_id"`
|
||||
}
|
||||
|
||||
// MomentLink 朋友圈网页链接
|
||||
type MomentLink struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// MomentLocation 朋友圈地理位置
|
||||
type MomentLocation struct {
|
||||
Latitude string `json:"latitude"`
|
||||
Longitude string `json:"longitude"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// GetMomentList 获取企业全部的发表列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93333#%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E5%85%A8%E9%83%A8%E7%9A%84%E5%8F%91%E8%A1%A8%E5%88%97%E8%A1%A8
|
||||
func (r *Client) GetMomentList(req *GetMomentListRequest) (*GetMomentListResponse, 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(getMomentListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentTaskRequest 获取客户朋友圈企业发表的列表请求
|
||||
type GetMomentTaskRequest struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetMomentTaskResponse 获取客户朋友圈企业发表的列表响应
|
||||
type GetMomentTaskResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
TaskList []MomentTask `json:"task_list"`
|
||||
}
|
||||
|
||||
// MomentTask 发表任务
|
||||
type MomentTask struct {
|
||||
UserID string `json:"userid"`
|
||||
PublishStatus int `json:"publish_status"`
|
||||
}
|
||||
|
||||
// GetMomentTask 获取客户朋友圈企业发表的列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93333#%E8%8E%B7%E5%8F%96%E5%AE%A2%E6%88%B7%E6%9C%8B%E5%8F%8B%E5%9C%88%E4%BC%81%E4%B8%9A%E5%8F%91%E8%A1%A8%E7%9A%84%E5%88%97%E8%A1%A8
|
||||
func (r *Client) GetMomentTask(req *GetMomentTaskRequest) (*GetMomentTaskResponse, 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(getMomentTaskURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentTaskResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentTask")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentCustomerListRequest 获取客户朋友圈发表时选择的可见范围请求
|
||||
type GetMomentCustomerListRequest struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
UserID string `json:"userid"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetMomentCustomerListResponse 获取客户朋友圈发表时选择的可见范围响应
|
||||
type GetMomentCustomerListResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
CustomerList []MomentCustomer `json:"customer_list"`
|
||||
}
|
||||
|
||||
// MomentCustomer 成员可见客户列表
|
||||
type MomentCustomer struct {
|
||||
UserID string `json:"userid"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
}
|
||||
|
||||
// GetMomentCustomerList 获取客户朋友圈发表时选择的可见范围
|
||||
// see https://developer.work.weixin.qq.com/document/path/93333#%E8%8E%B7%E5%8F%96%E5%AE%A2%E6%88%B7%E6%9C%8B%E5%8F%8B%E5%9C%88%E5%8F%91%E8%A1%A8%E6%97%B6%E9%80%89%E6%8B%A9%E7%9A%84%E5%8F%AF%E8%A7%81%E8%8C%83%E5%9B%B4
|
||||
func (r *Client) GetMomentCustomerList(req *GetMomentCustomerListRequest) (*GetMomentCustomerListResponse, 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(getMomentCustomerListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentCustomerListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentCustomerList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentSendResultRequest 获取客户朋友圈发表后的可见客户列表请求
|
||||
type GetMomentSendResultRequest struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
UserID string `json:"userid"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetMomentSendResultResponse 获取客户朋友圈发表后的可见客户列表响应
|
||||
type GetMomentSendResultResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
CustomerList []MomentSendCustomer `json:"customer_list"`
|
||||
}
|
||||
|
||||
// MomentSendCustomer 成员发送成功客户
|
||||
type MomentSendCustomer struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
}
|
||||
|
||||
// GetMomentSendResult 获取客户朋友圈发表后的可见客户列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93333#%E8%8E%B7%E5%8F%96%E5%AE%A2%E6%88%B7%E6%9C%8B%E5%8F%8B%E5%9C%88%E5%8F%91%E8%A1%A8%E5%90%8E%E7%9A%84%E5%8F%AF%E8%A7%81%E5%AE%A2%E6%88%B7%E5%88%97%E8%A1%A8
|
||||
func (r *Client) GetMomentSendResult(req *GetMomentSendResultRequest) (*GetMomentSendResultResponse, 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(getMomentSendResultURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentSendResultResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentSendResult")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentCommentsRequest 获取客户朋友圈的互动数据请求
|
||||
type GetMomentCommentsRequest struct {
|
||||
MomentID string `json:"moment_id"`
|
||||
UserID string `json:"userid"`
|
||||
}
|
||||
|
||||
// GetMomentCommentsResponse 获取客户朋友圈的互动数据响应
|
||||
type GetMomentCommentsResponse struct {
|
||||
util.CommonError
|
||||
CommentList []MomentComment `json:"comment_list"`
|
||||
LikeList []MomentLike `json:"like_list"`
|
||||
}
|
||||
|
||||
// MomentComment 朋友圈评论
|
||||
type MomentComment struct {
|
||||
ExternalUserID string `json:"external_userid,omitempty"`
|
||||
UserID string `json:"userid,omitempty"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
}
|
||||
|
||||
// MomentLike 朋友圈点赞
|
||||
type MomentLike struct {
|
||||
ExternalUserID string `json:"external_userid,omitempty"`
|
||||
UserID string `json:"userid,omitempty"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
}
|
||||
|
||||
// GetMomentComments 获取客户朋友圈的互动数据
|
||||
// see https://developer.work.weixin.qq.com/document/path/93333#%E8%8E%B7%E5%8F%96%E5%AE%A2%E6%88%B7%E6%9C%8B%E5%8F%8B%E5%9C%88%E7%9A%84%E4%BA%92%E5%8A%A8%E6%95%B0%E6%8D%AE
|
||||
func (r *Client) GetMomentComments(req *GetMomentCommentsRequest) (*GetMomentCommentsResponse, 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(getMomentCommentsURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentCommentsResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentComments")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ListMomentStrategyRequest 获取规则组列表请求
|
||||
type ListMomentStrategyRequest struct {
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// ListMomentStrategyResponse 获取规则组列表响应
|
||||
type ListMomentStrategyResponse struct {
|
||||
util.CommonError
|
||||
Strategy []MomentStrategyID `json:"strategy"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// MomentStrategyID 规则组ID
|
||||
type MomentStrategyID struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// ListMomentStrategy 获取规则组列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8
|
||||
func (r *Client) ListMomentStrategy(req *ListMomentStrategyRequest) (*ListMomentStrategyResponse, 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(listMomentStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListMomentStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListMomentStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetMomentStrategyRequest 获取规则组详情请求
|
||||
type GetMomentStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// GetMomentStrategyResponse 获取规则组详情响应
|
||||
type GetMomentStrategyResponse struct {
|
||||
util.CommonError
|
||||
Strategy MomentStrategy `json:"strategy"`
|
||||
}
|
||||
|
||||
// MomentStrategy 规则组
|
||||
type MomentStrategy struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
ParentID int `json:"parent_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege MomentPrivilege `json:"privilege"`
|
||||
}
|
||||
|
||||
// MomentPrivilege 规则组权限
|
||||
type MomentPrivilege struct {
|
||||
ViewMomentList bool `json:"view_moment_list"`
|
||||
SendMoment bool `json:"send_moment"`
|
||||
ManageMomentCoverAndSign bool `json:"manage_moment_cover_and_sign"`
|
||||
}
|
||||
|
||||
// GetMomentStrategy 获取规则组详情
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85
|
||||
func (r *Client) GetMomentStrategy(req *GetMomentStrategyRequest) (*GetMomentStrategyResponse, 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(getMomentStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetMomentStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetMomentStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetRangeMomentStrategyRequest 获取规则组管理范围请求
|
||||
type GetRangeMomentStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GetRangeMomentStrategyResponse 获取规则组管理范围响应
|
||||
type GetRangeMomentStrategyResponse struct {
|
||||
util.CommonError
|
||||
Range []RangeMomentStrategy `json:"range"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// RangeMomentStrategy 管理范围内配置的成员或部门
|
||||
type RangeMomentStrategy struct {
|
||||
Type int `json:"type"`
|
||||
UserID string `json:"userid,omitempty"`
|
||||
PartyID int `json:"partyid,omitempty"`
|
||||
}
|
||||
|
||||
// GetRangeMomentStrategy 获取规则组管理范围
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
|
||||
func (r *Client) GetRangeMomentStrategy(req *GetRangeMomentStrategyRequest) (*GetRangeMomentStrategyResponse, 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(getRangeMomentStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetRangeMomentStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetRangeMomentStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// CreateMomentStrategyRequest 创建新的规则组请求
|
||||
type CreateMomentStrategyRequest struct {
|
||||
ParentID int `json:"parent_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege MomentPrivilege `json:"privilege"`
|
||||
Range []RangeMomentStrategy `json:"range"`
|
||||
}
|
||||
|
||||
// CreateMomentStrategyResponse 创建新的规则组响应
|
||||
type CreateMomentStrategyResponse struct {
|
||||
util.CommonError
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// CreateMomentStrategy 创建新的规则组
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84
|
||||
func (r *Client) CreateMomentStrategy(req *CreateMomentStrategyRequest) (*CreateMomentStrategyResponse, 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(createMomentStrategyURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &CreateMomentStrategyResponse{}
|
||||
err = util.DecodeWithError(response, result, "CreateMomentStrategy")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// EditMomentStrategyRequest 编辑规则组及其管理范围请求
|
||||
type EditMomentStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
StrategyName string `json:"strategy_name"`
|
||||
AdminList []string `json:"admin_list"`
|
||||
Privilege MomentPrivilege `json:"privilege"`
|
||||
RangeAdd []RangeMomentStrategy `json:"range_add"`
|
||||
RangeDel []RangeMomentStrategy `json:"range_del"`
|
||||
}
|
||||
|
||||
// EditMomentStrategy 编辑规则组及其管理范围
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
|
||||
func (r *Client) EditMomentStrategy(req *EditMomentStrategyRequest) 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(editMomentStrategyURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "EditMomentStrategy")
|
||||
}
|
||||
|
||||
// DelMomentStrategyRequest 删除规则组请求
|
||||
type DelMomentStrategyRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
}
|
||||
|
||||
// DelMomentStrategy 删除规则组
|
||||
// see https://developer.work.weixin.qq.com/document/path/94890#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84
|
||||
func (r *Client) DelMomentStrategy(req *DelMomentStrategyRequest) 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(delMomentStrategyURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelMomentStrategy")
|
||||
}
|
||||
@@ -7,24 +7,28 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// AddMsgTemplateURL 创建企业群发
|
||||
AddMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
|
||||
// GetGroupMsgListV2URL 获取群发记录列表
|
||||
GetGroupMsgListV2URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2?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"
|
||||
// AddGroupWelcomeTemplateURL 添加入群欢迎语素材
|
||||
AddGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=%s"
|
||||
// EditGroupWelcomeTemplateURL 编辑入群欢迎语素材
|
||||
EditGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=%s"
|
||||
// GetGroupWelcomeTemplateURL 获取入群欢迎语素材
|
||||
GetGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/get?access_token=%s"
|
||||
// DelGroupWelcomeTemplateURL 删除入群欢迎语素材
|
||||
DelGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=%s"
|
||||
// addMsgTemplateURL 创建企业群发
|
||||
addMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
|
||||
// getGroupMsgListV2URL 获取群发记录列表
|
||||
getGroupMsgListV2URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2?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"
|
||||
// addGroupWelcomeTemplateURL 添加入群欢迎语素材
|
||||
addGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=%s"
|
||||
// editGroupWelcomeTemplateURL 编辑入群欢迎语素材
|
||||
editGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=%s"
|
||||
// getGroupWelcomeTemplateURL 获取入群欢迎语素材
|
||||
getGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/get?access_token=%s"
|
||||
// delGroupWelcomeTemplateURL 删除入群欢迎语素材
|
||||
delGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=%s"
|
||||
// remindGroupMsgSendURL 提醒成员群发
|
||||
remindGroupMsgSendURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remind_groupmsg_send?access_token=%s"
|
||||
// cancelGroupMsgSendURL 停止企业群发
|
||||
cancelGroupMsgSendURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/cancel_groupmsg_send?access_token=%s"
|
||||
)
|
||||
|
||||
// AddMsgTemplateRequest 创建企业群发请求
|
||||
@@ -34,8 +38,23 @@ type AddMsgTemplateRequest struct {
|
||||
Sender string `json:"sender,omitempty"`
|
||||
Text MsgText `json:"text"`
|
||||
Attachments []*Attachment `json:"attachments"`
|
||||
AllowSelect bool `json:"allow_select,omitempty"`
|
||||
ChatIDList []string `json:"chat_id_list,omitempty"`
|
||||
TagFilter TagFilter `json:"tag_filter,omitempty"`
|
||||
}
|
||||
|
||||
type (
|
||||
// TagFilter 标签过滤
|
||||
TagFilter struct {
|
||||
GroupList []TagGroupList `json:"group_list"`
|
||||
}
|
||||
|
||||
// TagGroupList 标签组
|
||||
TagGroupList struct {
|
||||
TagList []string `json:"tag_list"`
|
||||
}
|
||||
)
|
||||
|
||||
// MsgText 文本消息
|
||||
type MsgText struct {
|
||||
Content string `json:"content"`
|
||||
@@ -98,21 +117,19 @@ func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResp
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddMsgTemplateURL, accessToken), req); err != nil {
|
||||
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
|
||||
err = util.DecodeWithError(response, result, "AddMsgTemplate")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetGroupMsgListV2Request 获取群发记录列表请求
|
||||
type GetGroupMsgListV2Request struct {
|
||||
ChatType string `json:"chat_type"`
|
||||
StartTime int `json:"start_time"`
|
||||
EndTime int `json:"end_time"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
FilterType int `json:"filter_type"`
|
||||
Limit int `json:"limit"`
|
||||
@@ -130,7 +147,7 @@ type GetGroupMsgListV2Response struct {
|
||||
type GroupMsg struct {
|
||||
MsgID string `json:"msgid"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime int `json:"create_time"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
CreateType int `json:"create_type"`
|
||||
Text MsgText `json:"text"`
|
||||
Attachments []*Attachment `json:"attachments"`
|
||||
@@ -147,14 +164,12 @@ func (r *Client) GetGroupMsgListV2(req *GetGroupMsgListV2Request) (*GetGroupMsgL
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgListV2URL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getGroupMsgListV2URL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupMsgListV2Response{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupMsgListV2"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetGroupMsgListV2")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetGroupMsgTaskRequest 获取群发成员发送任务列表请求
|
||||
@@ -189,14 +204,12 @@ func (r *Client) GetGroupMsgTask(req *GetGroupMsgTaskRequest) (*GetGroupMsgTaskR
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgTaskURL, accessToken), req); err != nil {
|
||||
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
|
||||
err = util.DecodeWithError(response, result, "GetGroupMsgTask")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetGroupMsgSendResultRequest 获取企业群发成员执行结果请求
|
||||
@@ -234,14 +247,12 @@ func (r *Client) GetGroupMsgSendResult(req *GetGroupMsgSendResultRequest) (*GetG
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgSendResultURL, accessToken), req); err != nil {
|
||||
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
|
||||
err = util.DecodeWithError(response, result, "GetGroupMsgSendResult")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// SendWelcomeMsgRequest 发送新客户欢迎语请求
|
||||
@@ -267,26 +278,23 @@ func (r *Client) SendWelcomeMsg(req *SendWelcomeMsgRequest) error {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(SendWelcomeMsgURL, accessToken), req); err != nil {
|
||||
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
|
||||
return util.DecodeWithError(response, result, "SendWelcomeMsg")
|
||||
}
|
||||
|
||||
// AddGroupWelcomeTemplateRequest 添加入群欢迎语素材请求
|
||||
type AddGroupWelcomeTemplateRequest struct {
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
AgentID int `json:"agentid"`
|
||||
Notify int `json:"notify"`
|
||||
Text MsgText `json:"text"`
|
||||
Image *AttachmentImg `json:"image,omitempty"`
|
||||
Link *AttachmentLink `json:"link,omitempty"`
|
||||
MiniProgram *AttachmentMiniProgram `json:"miniprogram,omitempty"`
|
||||
File *AttachmentFile `json:"file,omitempty"`
|
||||
Video *AttachmentVideo `json:"video,omitempty"`
|
||||
AgentID int `json:"agentid,omitempty"`
|
||||
Notify int `json:"notify,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupWelcomeTemplateResponse 添加入群欢迎语素材响应
|
||||
@@ -306,26 +314,24 @@ func (r *Client) AddGroupWelcomeTemplate(req *AddGroupWelcomeTemplateRequest) (*
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(addGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddGroupWelcomeTemplate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "AddGroupWelcomeTemplate")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// EditGroupWelcomeTemplateRequest 编辑入群欢迎语素材请求
|
||||
type EditGroupWelcomeTemplateRequest struct {
|
||||
TemplateID string `json:"template_id"`
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
AgentID int `json:"agentid"`
|
||||
TemplateID string `json:"template_id"`
|
||||
Text MsgText `json:"text"`
|
||||
Image *AttachmentImg `json:"image"`
|
||||
Link *AttachmentLink `json:"link"`
|
||||
MiniProgram *AttachmentMiniProgram `json:"miniprogram"`
|
||||
File *AttachmentFile `json:"file"`
|
||||
Video *AttachmentVideo `json:"video"`
|
||||
AgentID int `json:"agentid"`
|
||||
}
|
||||
|
||||
// EditGroupWelcomeTemplateResponse 编辑入群欢迎语素材响应
|
||||
@@ -344,14 +350,11 @@ func (r *Client) EditGroupWelcomeTemplate(req *EditGroupWelcomeTemplateRequest)
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(EditGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(editGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
result := &EditGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "EditGroupWelcomeTemplate"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return util.DecodeWithError(response, result, "EditGroupWelcomeTemplate")
|
||||
}
|
||||
|
||||
// GetGroupWelcomeTemplateRequest 获取入群欢迎语素材请求
|
||||
@@ -363,11 +366,11 @@ type GetGroupWelcomeTemplateRequest struct {
|
||||
type GetGroupWelcomeTemplateResponse struct {
|
||||
util.CommonError
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
Image AttachmentImg `json:"image,omitempty"`
|
||||
Link AttachmentLink `json:"link,omitempty"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram,omitempty"`
|
||||
File AttachmentFile `json:"file,omitempty"`
|
||||
Video AttachmentVideo `json:"video,omitempty"`
|
||||
}
|
||||
|
||||
// GetGroupWelcomeTemplate 获取入群欢迎语素材
|
||||
@@ -381,14 +384,12 @@ func (r *Client) GetGroupWelcomeTemplate(req *GetGroupWelcomeTemplateRequest) (*
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupWelcomeTemplate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
err = util.DecodeWithError(response, result, "GetGroupWelcomeTemplate")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// DelGroupWelcomeTemplateRequest 删除入群欢迎语素材请求
|
||||
@@ -413,12 +414,53 @@ func (r *Client) DelGroupWelcomeTemplate(req *DelGroupWelcomeTemplateRequest) er
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(DelGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
if response, err = util.PostJSON(fmt.Sprintf(delGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
result := &DelGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "DelGroupWelcomeTemplate"); err != nil {
|
||||
return util.DecodeWithError(response, result, "DelGroupWelcomeTemplate")
|
||||
}
|
||||
|
||||
// RemindGroupMsgSendRequest 提醒成员群发请求
|
||||
type RemindGroupMsgSendRequest struct {
|
||||
MsgID string `json:"msgid"`
|
||||
}
|
||||
|
||||
// RemindGroupMsgSend 提醒成员群发
|
||||
// see https://developer.work.weixin.qq.com/document/path/97610
|
||||
func (r *Client) RemindGroupMsgSend(req *RemindGroupMsgSendRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(remindGroupMsgSendURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "RemindGroupMsgSend")
|
||||
}
|
||||
|
||||
// CancelGroupMsgSendRequest 停止企业群发请求
|
||||
type CancelGroupMsgSendRequest struct {
|
||||
MsgID string `json:"msgid"`
|
||||
}
|
||||
|
||||
// CancelGroupMsgSend 提醒成员群发
|
||||
// see https://developer.work.weixin.qq.com/document/path/97611
|
||||
func (r *Client) CancelGroupMsgSend(req *CancelGroupMsgSendRequest) 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(cancelGroupMsgSendURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "CancelGroupMsgSend")
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// GetUserBehaviorDataURL 获取「联系客户统计」数据
|
||||
GetUserBehaviorDataURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data"
|
||||
// GetGroupChatStatURL 获取「群聊数据统计」数据 按群主聚合的方式
|
||||
GetGroupChatStatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic"
|
||||
// GetGroupChatStatByDayURL 获取「群聊数据统计」数据 按自然日聚合的方式
|
||||
GetGroupChatStatByDayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day"
|
||||
// getUserBehaviorDataURL 获取「联系客户统计」数据
|
||||
getUserBehaviorDataURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data"
|
||||
// getGroupChatStatURL 获取「群聊数据统计」数据 按群主聚合的方式
|
||||
getGroupChatStatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic"
|
||||
// getGroupChatStatByDayURL 获取「群聊数据统计」数据 按自然日聚合的方式
|
||||
getGroupChatStatByDayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -54,16 +54,13 @@ func (r *Client) GetUserBehaviorData(req *GetUserBehaviorRequest) ([]BehaviorDat
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetUserBehaviorDataURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getUserBehaviorDataURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetUserBehaviorResponse
|
||||
err = util.DecodeWithError(response, &result, "GetUserBehaviorData")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.BehaviorData, nil
|
||||
return result.BehaviorData, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -120,16 +117,13 @@ func (r *Client) GetGroupChatStat(req *GetGroupChatStatRequest) (*GetGroupChatSt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getGroupChatStatURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupChatStatResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetGroupChatStat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
return result, err
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -163,14 +157,11 @@ func (r *Client) GetGroupChatStatByDay(req *GetGroupChatStatByDayRequest) ([]Get
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatByDayURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getGroupChatStatByDayURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetGroupChatStatByDayResponse
|
||||
err = util.DecodeWithError(response, &result, "GetGroupChatStatByDay")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.Items, nil
|
||||
return result.Items, err
|
||||
}
|
||||
|
||||
@@ -8,16 +8,24 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// GetCropTagURL 获取标签列表
|
||||
GetCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list"
|
||||
// AddCropTagURL 添加标签
|
||||
AddCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag"
|
||||
// EditCropTagURL 修改标签
|
||||
EditCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag"
|
||||
// DelCropTagURL 删除标签
|
||||
DelCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
|
||||
// MarkCropTagURL 为客户打上、删除标签
|
||||
MarkCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag"
|
||||
// getCropTagURL 获取标签列表
|
||||
getCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list"
|
||||
// addCropTagURL 添加标签
|
||||
addCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag"
|
||||
// editCropTagURL 修改标签
|
||||
editCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag"
|
||||
// delCropTagURL 删除标签
|
||||
delCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
|
||||
// markCropTagURL 为客户打上、删除标签
|
||||
markCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag"
|
||||
// getStrategyTagListURL 获取指定规则组下的企业客户标签
|
||||
getStrategyTagListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_strategy_tag_list?access_token=%s"
|
||||
// addStrategyTagURL 为指定规则组创建企业客户标签
|
||||
addStrategyTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_strategy_tag?access_token=%s"
|
||||
// editStrategyTagURL 编辑指定规则组下的企业客户标签
|
||||
editStrategyTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_strategy_tag?access_token=%s"
|
||||
// delStrategyTagURL 删除指定规则组下的企业客户标签
|
||||
delStrategyTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_strategy_tag?access_token=%s"
|
||||
)
|
||||
|
||||
// GetCropTagRequest 获取企业标签请求
|
||||
@@ -36,7 +44,7 @@ type GetCropTagListResponse struct {
|
||||
type TagGroup struct {
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
CreateTime int `json:"create_time"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
GroupOrder int `json:"group_order"`
|
||||
Deleted bool `json:"deleted"`
|
||||
Tag []TagGroupTagItem `json:"tag"`
|
||||
@@ -46,7 +54,7 @@ type TagGroup struct {
|
||||
type TagGroupTagItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreateTime int `json:"create_time"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
@@ -63,16 +71,13 @@ func (r *Client) GetCropTagList(req GetCropTagRequest) ([]TagGroup, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetCropTagURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetCropTagListResponse
|
||||
err = util.DecodeWithError(response, &result, "GetCropTagList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.TagGroup, nil
|
||||
return result.TagGroup, err
|
||||
}
|
||||
|
||||
// AddCropTagRequest 添加企业标签请求
|
||||
@@ -109,16 +114,13 @@ func (r *Client) AddCropTag(req AddCropTagRequest) (*TagGroup, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", AddCropTagURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", addCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result AddCropTagResponse
|
||||
err = util.DecodeWithError(response, &result, "AddCropTag")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result.TagGroup, nil
|
||||
return &result.TagGroup, err
|
||||
}
|
||||
|
||||
// EditCropTagRequest 编辑客户企业标签请求
|
||||
@@ -141,7 +143,7 @@ func (r *Client) EditCropTag(req EditCropTagRequest) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", EditCropTagURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", editCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -167,7 +169,7 @@ func (r *Client) DeleteCropTag(req DeleteCropTagRequest) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", DelCropTagURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", delCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -195,9 +197,163 @@ func (r *Client) MarkTag(request MarkTagRequest) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", MarkCropTagURL, accessToken), string(jsonData))
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", markCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "MarkTag")
|
||||
}
|
||||
|
||||
// GetStrategyTagListRequest 获取指定规则组下的企业客户标签请求
|
||||
type GetStrategyTagListRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
TagID []string `json:"tag_id"`
|
||||
GroupID []string `json:"group_id"`
|
||||
}
|
||||
|
||||
// GetStrategyTagListResponse 获取指定规则组下的企业客户标签响应
|
||||
type GetStrategyTagListResponse struct {
|
||||
util.CommonError
|
||||
TagGroup []StrategyTagGroup `json:"tag_group"`
|
||||
}
|
||||
|
||||
// StrategyTagGroup 规则组下的企业标签组
|
||||
type StrategyTagGroup struct {
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
StrategyID int `json:"strategy_id"`
|
||||
Tag []StrategyTag `json:"tag"`
|
||||
}
|
||||
|
||||
// StrategyTag 规则组下的企业标签
|
||||
type StrategyTag struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// GetStrategyTagList 获取指定规则组下的企业客户标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94882#%E8%8E%B7%E5%8F%96%E6%8C%87%E5%AE%9A%E8%A7%84%E5%88%99%E7%BB%84%E4%B8%8B%E7%9A%84%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E6%A0%87%E7%AD%BE
|
||||
func (r *Client) GetStrategyTagList(req *GetStrategyTagListRequest) (*GetStrategyTagListResponse, 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(getStrategyTagListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetStrategyTagListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetStrategyTagList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// AddStrategyTagRequest 为指定规则组创建企业客户标签请求
|
||||
type AddStrategyTagRequest struct {
|
||||
StrategyID int `json:"strategy_id"`
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
Order int `json:"order"`
|
||||
Tag []AddStrategyTagRequestItem `json:"tag"`
|
||||
}
|
||||
|
||||
// AddStrategyTagRequestItem 为指定规则组创建企业客户标签请求条目
|
||||
type AddStrategyTagRequestItem struct {
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// AddStrategyTagResponse 为指定规则组创建企业客户标签响应
|
||||
type AddStrategyTagResponse struct {
|
||||
util.CommonError
|
||||
TagGroup AddStrategyTagResponseTagGroup `json:"tag_group"`
|
||||
}
|
||||
|
||||
// AddStrategyTagResponseTagGroup 为指定规则组创建企业客户标签响应标签组
|
||||
type AddStrategyTagResponseTagGroup struct {
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
Tag []AddStrategyTagResponseItem `json:"tag"`
|
||||
}
|
||||
|
||||
// AddStrategyTagResponseItem 标签组内的标签列表
|
||||
type AddStrategyTagResponseItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// AddStrategyTag 为指定规则组创建企业客户标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94882#%E4%B8%BA%E6%8C%87%E5%AE%9A%E8%A7%84%E5%88%99%E7%BB%84%E5%88%9B%E5%BB%BA%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E6%A0%87%E7%AD%BE
|
||||
func (r *Client) AddStrategyTag(req *AddStrategyTagRequest) (*AddStrategyTagResponse, 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(addStrategyTagURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddStrategyTagResponse{}
|
||||
err = util.DecodeWithError(response, result, "AddStrategyTag")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// EditStrategyTagRequest 编辑指定规则组下的企业客户标签请求
|
||||
type EditStrategyTagRequest struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// EditStrategyTag 编辑指定规则组下的企业客户标签
|
||||
// see https://developer.work.weixin.qq.com/document/path/94882#%E7%BC%96%E8%BE%91%E6%8C%87%E5%AE%9A%E8%A7%84%E5%88%99%E7%BB%84%E4%B8%8B%E7%9A%84%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E6%A0%87%E7%AD%BE
|
||||
func (r *Client) EditStrategyTag(req *EditStrategyTagRequest) 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(editStrategyTagURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "EditStrategyTag")
|
||||
}
|
||||
|
||||
// DelStrategyTagRequest 删除指定规则组下的企业客户标签请求
|
||||
type DelStrategyTagRequest struct {
|
||||
TagID []string `json:"tag_id"`
|
||||
GroupID []string `json:"group_id"`
|
||||
}
|
||||
|
||||
// DelStrategyTag 删除指定规则组下的企业客户标签
|
||||
// see https://developer.work.weixin.qq.com/document/path/94882#%E5%88%A0%E9%99%A4%E6%8C%87%E5%AE%9A%E8%A7%84%E5%88%99%E7%BB%84%E4%B8%8B%E7%9A%84%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E6%A0%87%E7%AD%BE
|
||||
func (r *Client) DelStrategyTag(req *DelStrategyTagRequest) 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(delStrategyTagURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelStrategyTag")
|
||||
}
|
||||
|
||||
277
work/externalcontact/transfer.go
Normal file
277
work/externalcontact/transfer.go
Normal file
@@ -0,0 +1,277 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// transferCustomerURL 分配在职成员的客户
|
||||
transferCustomerURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/transfer_customer?access_token=%s"
|
||||
// transferResultURL 查询客户接替状态
|
||||
transferResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/transfer_result?access_token=%s"
|
||||
// groupChatOnJobTransferURL 分配在职成员的客户群
|
||||
groupChatOnJobTransferURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/onjob_transfer?access_token=%s"
|
||||
// getUnassignedListURL 获取待分配的离职成员列表
|
||||
getUnassignedListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=%s"
|
||||
// resignedTransferCustomerURL 分配离职成员的客户
|
||||
resignedTransferCustomerURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?access_token=%s"
|
||||
// resignedTransferResultURL 查询离职客户接替状态
|
||||
resignedTransferResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_result?access_token=%s"
|
||||
// groupChatTransferURL 分配离职成员的客户群
|
||||
groupChatTransferURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/transfer?access_token=%s"
|
||||
)
|
||||
|
||||
// TransferCustomerRequest 分配在职成员的客户请求
|
||||
type TransferCustomerRequest struct {
|
||||
HandoverUserID string `json:"handover_userid"`
|
||||
TakeoverUserID string `json:"takeover_userid"`
|
||||
ExternalUserID []string `json:"external_userid"`
|
||||
TransferSuccessMsg string `json:"transfer_success_msg"`
|
||||
}
|
||||
|
||||
// TransferCustomerResponse 分配在职成员的客户请求响应
|
||||
type TransferCustomerResponse struct {
|
||||
util.CommonError
|
||||
Customer []TransferCustomerItem `json:"customer"`
|
||||
}
|
||||
|
||||
// TransferCustomerItem 客户分配结果
|
||||
type TransferCustomerItem struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
ErrCode int `json:"errcode"`
|
||||
}
|
||||
|
||||
// TransferCustomer 分配在职成员的客户
|
||||
// see https://developer.work.weixin.qq.com/document/path/92125
|
||||
func (r *Client) TransferCustomer(req *TransferCustomerRequest) (*TransferCustomerResponse, 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(transferCustomerURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &TransferCustomerResponse{}
|
||||
err = util.DecodeWithError(response, result, "TransferCustomer")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// TransferResultRequest 查询客户接替状态请求
|
||||
type TransferResultRequest struct {
|
||||
HandoverUserID string `json:"handover_userid"`
|
||||
TakeoverUserID string `json:"takeover_userid"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// TransferResultResponse 查询客户接替状态响应
|
||||
type TransferResultResponse struct {
|
||||
util.CommonError
|
||||
Customer []TransferResultItem `json:"customer"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// TransferResultItem 客户接替状态
|
||||
type TransferResultItem struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Status int `json:"status"`
|
||||
TakeoverTime int64 `json:"takeover_time"`
|
||||
}
|
||||
|
||||
// TransferResult 查询客户接替状态
|
||||
// see https://developer.work.weixin.qq.com/document/path/94088
|
||||
func (r *Client) TransferResult(req *TransferResultRequest) (*TransferResultResponse, 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(transferResultURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &TransferResultResponse{}
|
||||
err = util.DecodeWithError(response, result, "TransferResult")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GroupChatOnJobTransferRequest 分配在职成员的客户群请求
|
||||
type GroupChatOnJobTransferRequest struct {
|
||||
ChatIDList []string `json:"chat_id_list"`
|
||||
NewOwner string `json:"new_owner"`
|
||||
}
|
||||
|
||||
// GroupChatOnJobTransferResponse 分配在职成员的客户群响应
|
||||
type GroupChatOnJobTransferResponse struct {
|
||||
util.CommonError
|
||||
FailedChatList []FailedChat `json:"failed_chat_list"`
|
||||
}
|
||||
|
||||
// FailedChat 没能成功继承的群
|
||||
type FailedChat struct {
|
||||
ChatID string `json:"chat_id"`
|
||||
ErrCode int `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
// GroupChatOnJobTransfer 分配在职成员的客户群
|
||||
// see https://developer.work.weixin.qq.com/document/path/95703
|
||||
func (r *Client) GroupChatOnJobTransfer(req *GroupChatOnJobTransferRequest) (*GroupChatOnJobTransferResponse, 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(groupChatOnJobTransferURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatOnJobTransferResponse{}
|
||||
err = util.DecodeWithError(response, result, "GroupChatOnJobTransfer")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetUnassignedListRequest 获取待分配的离职成员列表请求
|
||||
type GetUnassignedListRequest struct {
|
||||
Cursor string `json:"cursor"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// GetUnassignedListResponse 获取待分配的离职成员列表响应
|
||||
type GetUnassignedListResponse struct {
|
||||
util.CommonError
|
||||
Info []UnassignedListInfo `json:"info"`
|
||||
IsLast bool `json:"is_last"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// UnassignedListInfo 离职成员信息
|
||||
type UnassignedListInfo struct {
|
||||
HandoverUserID string `json:"handover_userid"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
DimissionTime int64 `json:"dimission_time"`
|
||||
}
|
||||
|
||||
// GetUnassignedList 获取待分配的离职成员列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/92124
|
||||
func (r *Client) GetUnassignedList(req *GetUnassignedListRequest) (*GetUnassignedListResponse, 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(getUnassignedListURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetUnassignedListResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetUnassignedList")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ResignedTransferCustomerRequest 分配离职成员的客户请求
|
||||
type ResignedTransferCustomerRequest struct {
|
||||
HandoverUserID string `json:"handover_userid"`
|
||||
TakeoverUserID string `json:"takeover_userid"`
|
||||
ExternalUserID []string `json:"external_userid"`
|
||||
}
|
||||
|
||||
// ResignedTransferCustomerResponse 分配离职成员的客户响应
|
||||
type ResignedTransferCustomerResponse struct {
|
||||
util.CommonError
|
||||
Customer []TransferCustomerItem `json:"customer"`
|
||||
}
|
||||
|
||||
// ResignedTransferCustomer 分配离职成员的客户
|
||||
// see https://developer.work.weixin.qq.com/document/path/94081
|
||||
func (r *Client) ResignedTransferCustomer(req *ResignedTransferCustomerRequest) (*ResignedTransferCustomerResponse, 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(resignedTransferCustomerURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ResignedTransferCustomerResponse{}
|
||||
err = util.DecodeWithError(response, result, "ResignedTransferCustomer")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ResignedTransferResultRequest 查询离职客户接替状态请求
|
||||
type ResignedTransferResultRequest struct {
|
||||
HandoverUserID string `json:"handover_userid"`
|
||||
TakeoverUserID string `json:"takeover_userid"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// ResignedTransferResultResponse 查询离职客户接替状态响应
|
||||
type ResignedTransferResultResponse struct {
|
||||
util.CommonError
|
||||
Customer []TransferResultItem `json:"customer"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// ResignedTransferResult 查询离职客户接替状态
|
||||
// see https://developer.work.weixin.qq.com/document/path/94082
|
||||
func (r *Client) ResignedTransferResult(req *ResignedTransferResultRequest) (*ResignedTransferResultResponse, 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(resignedTransferResultURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ResignedTransferResultResponse{}
|
||||
err = util.DecodeWithError(response, result, "ResignedTransferResult")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GroupChatTransferRequest 分配离职成员的客户群请求
|
||||
type GroupChatTransferRequest struct {
|
||||
ChatIDList []string `json:"chat_id_list"`
|
||||
NewOwner string `json:"new_owner"`
|
||||
}
|
||||
|
||||
// GroupChatTransferResponse 分配离职成员的客户群响应
|
||||
type GroupChatTransferResponse struct {
|
||||
util.CommonError
|
||||
FailedChatList []FailedChat `json:"failed_chat_list"`
|
||||
}
|
||||
|
||||
// GroupChatTransfer 分配离职成员的客户群
|
||||
// see https://developer.work.weixin.qq.com/document/path/92127
|
||||
func (r *Client) GroupChatTransfer(req *GroupChatTransferRequest) (*GroupChatTransferResponse, 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(groupChatTransferURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatTransferResponse{}
|
||||
err = util.DecodeWithError(response, result, "GroupChatTransfer")
|
||||
return result, err
|
||||
}
|
||||
17
work/invoice/client.go
Normal file
17
work/invoice/client.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package invoice
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/work/context"
|
||||
)
|
||||
|
||||
// Client 电子发票接口实例
|
||||
type Client struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewClient 初始化实例
|
||||
func NewClient(ctx *context.Context) *Client {
|
||||
return &Client{
|
||||
ctx,
|
||||
}
|
||||
}
|
||||
187
work/invoice/invoice.go
Normal file
187
work/invoice/invoice.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package invoice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// getInvoiceInfoURL 查询电子发票
|
||||
getInvoiceInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/getinvoiceinfo?access_token=%s"
|
||||
// updateInvoiceStatusURL 更新发票状态
|
||||
updateInvoiceStatusURL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/updateinvoicestatus?access_token=%s"
|
||||
// updateStatusBatchURL 批量更新发票状态
|
||||
updateStatusBatchURL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/updatestatusbatch?access_token=%s"
|
||||
// getInvoiceInfoBatchURL 批量查询电子发票
|
||||
getInvoiceInfoBatchURL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/getinvoiceinfobatch?access_token=%s"
|
||||
)
|
||||
|
||||
// GetInvoiceInfoRequest 查询电子发票请求
|
||||
type GetInvoiceInfoRequest struct {
|
||||
CardID string `json:"card_id"`
|
||||
EncryptCode string `json:"encrypt_code"`
|
||||
}
|
||||
|
||||
// GetInvoiceInfoResponse 查询电子发票响应
|
||||
type GetInvoiceInfoResponse struct {
|
||||
util.CommonError
|
||||
CardID string `json:"card_id"`
|
||||
BeginTime int64 `json:"begin_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
OpenID string `json:"openid"`
|
||||
Type string `json:"type"`
|
||||
Payee string `json:"payee"`
|
||||
Detail string `json:"detail"`
|
||||
UserInfo UserInfo `json:"user_info"`
|
||||
}
|
||||
|
||||
// UserInfo 发票的用户信息
|
||||
type UserInfo struct {
|
||||
Fee int64 `json:"fee"`
|
||||
Title string `json:"title"`
|
||||
BillingTime int64 `json:"billing_time"`
|
||||
BillingNo string `json:"billing_no"`
|
||||
BillingCode string `json:"billing_code"`
|
||||
Info []Info `json:"info"`
|
||||
FeeWithoutTax int64 `json:"fee_without_tax"`
|
||||
Tax int64 `json:"tax"`
|
||||
Detail string `json:"detail"`
|
||||
PdfURL string `json:"pdf_url"`
|
||||
TripPdfURL string `json:"trip_pdf_url"`
|
||||
ReimburseStatus string `json:"reimburse_status"`
|
||||
CheckCode string `json:"check_code"`
|
||||
BuyerNumber string `json:"buyer_number"`
|
||||
BuyerAddressAndPhone string `json:"buyer_address_and_phone"`
|
||||
BuyerBankAccount string `json:"buyer_bank_account"`
|
||||
SellerNumber string `json:"seller_number"`
|
||||
SellerAddressAndPhone string `json:"seller_address_and_phone"`
|
||||
SellerBankAccount string `json:"seller_bank_account"`
|
||||
Remarks string `json:"remarks"`
|
||||
Cashier string `json:"cashier"`
|
||||
Maker string `json:"maker"`
|
||||
}
|
||||
|
||||
// Info 商品信息结构
|
||||
type Info struct {
|
||||
Name string `json:"name"`
|
||||
Num int64 `json:"num"`
|
||||
Unit string `json:"unit"`
|
||||
Fee int64 `json:"fee"`
|
||||
Price int64 `json:"price"`
|
||||
}
|
||||
|
||||
// GetInvoiceInfo 查询电子发票
|
||||
// see https://developer.work.weixin.qq.com/document/path/90284
|
||||
func (r *Client) GetInvoiceInfo(req *GetInvoiceInfoRequest) (*GetInvoiceInfoResponse, 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(getInvoiceInfoURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetInvoiceInfoResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetInvoiceInfo")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UpdateInvoiceStatusRequest 更新发票状态请求
|
||||
type UpdateInvoiceStatusRequest struct {
|
||||
CardID string `json:"card_id"`
|
||||
EncryptCode string `json:"encrypt_code"`
|
||||
ReimburseStatus string `json:"reimburse_status"`
|
||||
}
|
||||
|
||||
// UpdateInvoiceStatus 更新发票状态
|
||||
// see https://developer.work.weixin.qq.com/document/path/90285
|
||||
func (r *Client) UpdateInvoiceStatus(req *UpdateInvoiceStatusRequest) 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(updateInvoiceStatusURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateInvoiceStatus")
|
||||
}
|
||||
|
||||
// UpdateStatusBatchRequest 批量更新发票状态
|
||||
type UpdateStatusBatchRequest struct {
|
||||
OpenID string `json:"openid"`
|
||||
ReimburseStatus string `json:"reimburse_status"`
|
||||
InvoiceList []Invoice `json:"invoice_list"`
|
||||
}
|
||||
|
||||
// Invoice 发票卡券
|
||||
type Invoice struct {
|
||||
CardID string `json:"card_id"`
|
||||
EncryptCode string `json:"encrypt_code"`
|
||||
}
|
||||
|
||||
// UpdateStatusBatch 批量更新发票状态
|
||||
// see https://developer.work.weixin.qq.com/document/path/90286
|
||||
func (r *Client) UpdateStatusBatch(req *UpdateStatusBatchRequest) 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(updateStatusBatchURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateStatusBatch")
|
||||
}
|
||||
|
||||
// GetInvoiceInfoBatchRequest 批量查询电子发票请求
|
||||
type GetInvoiceInfoBatchRequest struct {
|
||||
ItemList []Invoice `json:"item_list"`
|
||||
}
|
||||
|
||||
// GetInvoiceInfoBatchResponse 批量查询电子发票响应
|
||||
type GetInvoiceInfoBatchResponse struct {
|
||||
util.CommonError
|
||||
ItemList []Item `json:"item_list"`
|
||||
}
|
||||
|
||||
// Item 电子发票的结构化信息
|
||||
type Item struct {
|
||||
CardID string `json:"card_id"`
|
||||
BeginTime int64 `json:"begin_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
OpenID string `json:"openid"`
|
||||
Type string `json:"type"`
|
||||
Payee string `json:"payee"`
|
||||
Detail string `json:"detail"`
|
||||
UserInfo UserInfo `json:"user_info"`
|
||||
}
|
||||
|
||||
// GetInvoiceInfoBatch 批量查询电子发票
|
||||
// see https://developer.work.weixin.qq.com/document/path/90287
|
||||
func (r *Client) GetInvoiceInfoBatch(req *GetInvoiceInfoBatchRequest) (*GetInvoiceInfoBatchResponse, 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(getInvoiceInfoBatchURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetInvoiceInfoBatchResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetInvoiceInfoBatch")
|
||||
return result, err
|
||||
}
|
||||
@@ -52,11 +52,12 @@ type callbackOriginMessage struct {
|
||||
|
||||
// CallbackMessage 微信客服回调消息
|
||||
type CallbackMessage struct {
|
||||
ToUserName string `json:"to_user_name"` // 微信客服组件ID
|
||||
CreateTime int `json:"create_time"` // 消息创建时间,unix时间戳
|
||||
MsgType string `json:"msgtype"` // 消息的类型,此时固定为 event
|
||||
Event string `json:"event"` // 事件的类型,此时固定为 kf_msg_or_event
|
||||
Token string `json:"token"` // 调用拉取消息接口时,需要传此token,用于校验请求的合法性
|
||||
ToUserName string `json:"to_user_name" xml:"ToUserName"` // 微信客服组件ID
|
||||
CreateTime int64 `json:"create_time" xml:"CreateTime"` // 消息创建时间,unix时间戳
|
||||
MsgType string `json:"msgtype" xml:"MsgType"` // 消息的类型,此时固定为 event
|
||||
Event string `json:"event" xml:"Event"` // 事件的类型,此时固定为 kf_msg_or_event
|
||||
Token string `json:"token" xml:"Token"` // 调用拉取消息接口时,需要传此token,用于校验请求的合法性
|
||||
OpenKfID string `json:"open_kfid" xml:"OpenKfId"` // 有新消息的客服帐号。可通过sync_msg接口指定open_kfid获取此客服帐号的消息
|
||||
}
|
||||
|
||||
// GetCallbackMessage 获取回调事件中的消息内容
|
||||
@@ -91,8 +92,6 @@ func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg CallbackMessage, e
|
||||
if err != nil {
|
||||
return msg, NewSDKErr(40016)
|
||||
}
|
||||
if err = xml.Unmarshal(bData, &msg); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
err = xml.Unmarshal(bData, &msg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
359
work/kf/knowledge.go
Normal file
359
work/kf/knowledge.go
Normal file
@@ -0,0 +1,359 @@
|
||||
package kf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// addKnowledgeGroupURL 知识库分组添加
|
||||
addKnowledgeGroupURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/add_group?access_token=%s"
|
||||
// delKnowledgeGroupURL 知识库分组删除
|
||||
delKnowledgeGroupURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/del_group?access_token=%s"
|
||||
// modKnowledgeGroupURL 知识库分组修改
|
||||
modKnowledgeGroupURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/mod_group?access_token=%s"
|
||||
// listKnowledgeGroupURL 知识库分组列表
|
||||
listKnowledgeGroupURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/list_group?access_token=%s"
|
||||
// addKnowledgeIntentURL 知识库问答添加
|
||||
addKnowledgeIntentURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/add_intent?access_token=%s"
|
||||
// delKnowledgeIntentURL 知识库问答删除
|
||||
delKnowledgeIntentURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/del_intent?access_token=%s"
|
||||
// modKnowledgeIntentURL 知识库问答修改
|
||||
modKnowledgeIntentURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/mod_intent?access_token=%s"
|
||||
// listKnowledgeIntentURL 知识库问答列表
|
||||
listKnowledgeIntentURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/knowledge/list_intent?access_token=%s"
|
||||
)
|
||||
|
||||
// AddKnowledgeGroupRequest 知识库分组添加请求
|
||||
type AddKnowledgeGroupRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// AddKnowledgeGroupResponse 知识库分组添加响应
|
||||
type AddKnowledgeGroupResponse struct {
|
||||
util.CommonError
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// AddKnowledgeGroup 知识库分组添加
|
||||
// see https://developer.work.weixin.qq.com/document/path/95971#%E6%B7%BB%E5%8A%A0%E5%88%86%E7%BB%84
|
||||
func (r *Client) AddKnowledgeGroup(req *AddKnowledgeGroupRequest) (*AddKnowledgeGroupResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(addKnowledgeGroupURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddKnowledgeGroupResponse{}
|
||||
err = util.DecodeWithError(response, result, "AddKnowledgeGroup")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// DelKnowledgeGroupRequest 知识库分组删除请求
|
||||
type DelKnowledgeGroupRequest struct {
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// DelKnowledgeGroup 知识库分组删除
|
||||
// see https://developer.work.weixin.qq.com/document/path/95971#%E5%88%A0%E9%99%A4%E5%88%86%E7%BB%84
|
||||
func (r *Client) DelKnowledgeGroup(req *DelKnowledgeGroupRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(delKnowledgeGroupURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelKnowledgeGroup")
|
||||
}
|
||||
|
||||
// ModKnowledgeGroupRequest 知识库分组修改请求
|
||||
type ModKnowledgeGroupRequest struct {
|
||||
GroupID string `json:"group_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ModKnowledgeGroup 知识库分组修改
|
||||
// see https://developer.work.weixin.qq.com/document/path/95971#%E4%BF%AE%E6%94%B9%E5%88%86%E7%BB%84
|
||||
func (r *Client) ModKnowledgeGroup(req *ModKnowledgeGroupRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(modKnowledgeGroupURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "ModKnowledgeGroup")
|
||||
}
|
||||
|
||||
// ListKnowledgeGroupRequest 知识库分组列表请求
|
||||
type ListKnowledgeGroupRequest struct {
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// ListKnowledgeGroupResponse 知识库分组列表响应
|
||||
type ListKnowledgeGroupResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
HasMore int `json:"has_more"`
|
||||
GroupList []KnowledgeGroup `json:"group_list"`
|
||||
}
|
||||
|
||||
// KnowledgeGroup 知识库分组
|
||||
type KnowledgeGroup struct {
|
||||
GroupID string `json:"group_id"`
|
||||
Name string `json:"name"`
|
||||
IsDefault int `json:"is_default"`
|
||||
}
|
||||
|
||||
// ListKnowledgeGroup 知识库分组列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/95971#%E8%8E%B7%E5%8F%96%E5%88%86%E7%BB%84%E5%88%97%E8%A1%A8
|
||||
func (r *Client) ListKnowledgeGroup(req *ListKnowledgeGroupRequest) (*ListKnowledgeGroupResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(listKnowledgeGroupURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListKnowledgeGroupResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListKnowledgeGroup")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// AddKnowledgeIntentRequest 知识库问答添加请求
|
||||
type AddKnowledgeIntentRequest struct {
|
||||
GroupID string `json:"group_id"`
|
||||
Question IntentQuestion `json:"question"`
|
||||
SimilarQuestions IntentSimilarQuestions `json:"similar_questions"`
|
||||
Answers []IntentAnswerReq `json:"answers"`
|
||||
}
|
||||
|
||||
// IntentQuestion 主问题
|
||||
type IntentQuestion struct {
|
||||
Text IntentQuestionText `json:"text"`
|
||||
}
|
||||
|
||||
// IntentQuestionText 问题文本
|
||||
type IntentQuestionText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// IntentSimilarQuestions 相似问题
|
||||
type IntentSimilarQuestions struct {
|
||||
Items []IntentQuestion `json:"items"`
|
||||
}
|
||||
|
||||
// IntentAnswerReq 回答请求
|
||||
type IntentAnswerReq struct {
|
||||
Text IntentAnswerText `json:"text"`
|
||||
Attachments []IntentAnswerAttachmentReq `json:"attachments"`
|
||||
}
|
||||
|
||||
// IntentAnswerText 回答文本
|
||||
type IntentAnswerText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentReq 回答附件请求
|
||||
type IntentAnswerAttachmentReq struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
Image IntentAnswerAttachmentImgReq `json:"image,omitempty"`
|
||||
Video IntentAnswerAttachmentVideoReq `json:"video,omitempty"`
|
||||
Link IntentAnswerAttachmentLink `json:"link,omitempty"`
|
||||
MiniProgram IntentAnswerAttachmentMiniProgramReq `json:"miniprogram,omitempty"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentImgReq 图片类型回答附件请求
|
||||
type IntentAnswerAttachmentImgReq struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentVideoReq 视频类型回答附件请求
|
||||
type IntentAnswerAttachmentVideoReq struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentLink 链接类型回答附件
|
||||
type IntentAnswerAttachmentLink struct {
|
||||
Title string `json:"title"`
|
||||
PicURL string `json:"picurl"`
|
||||
Desc string `json:"desc"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentMiniProgramReq 小程序类型回答附件请求
|
||||
type IntentAnswerAttachmentMiniProgramReq struct {
|
||||
Title string `json:"title"`
|
||||
ThumbMediaID string `json:"thumb_media_id"`
|
||||
AppID string `json:"appid"`
|
||||
PagePath string `json:"pagepath"`
|
||||
}
|
||||
|
||||
// AddKnowledgeIntentResponse 知识库问答添加响应
|
||||
type AddKnowledgeIntentResponse struct {
|
||||
util.CommonError
|
||||
IntentID string `json:"intent_id"`
|
||||
}
|
||||
|
||||
// AddKnowledgeIntent 知识库问答添加
|
||||
// see https://developer.work.weixin.qq.com/document/path/95972#%E6%B7%BB%E5%8A%A0%E9%97%AE%E7%AD%94
|
||||
func (r *Client) AddKnowledgeIntent(req *AddKnowledgeIntentRequest) (*AddKnowledgeIntentResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(addKnowledgeIntentURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddKnowledgeIntentResponse{}
|
||||
err = util.DecodeWithError(response, result, "AddKnowledgeIntent")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// DelKnowledgeIntentRequest 知识库问答删除请求
|
||||
type DelKnowledgeIntentRequest struct {
|
||||
IntentID string `json:"intent_id"`
|
||||
}
|
||||
|
||||
// DelKnowledgeIntent 知识库问答删除
|
||||
// see https://developer.work.weixin.qq.com/document/path/95972#%E5%88%A0%E9%99%A4%E9%97%AE%E7%AD%94
|
||||
func (r *Client) DelKnowledgeIntent(req *DelKnowledgeIntentRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(delKnowledgeIntentURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelKnowledgeIntent")
|
||||
}
|
||||
|
||||
// ModKnowledgeIntentRequest 知识库问答修改请求
|
||||
type ModKnowledgeIntentRequest struct {
|
||||
IntentID string `json:"intent_id"`
|
||||
Question IntentQuestion `json:"question"`
|
||||
SimilarQuestions IntentSimilarQuestions `json:"similar_questions"`
|
||||
Answers []IntentAnswerReq `json:"answers"`
|
||||
}
|
||||
|
||||
// ModKnowledgeIntent 知识库问答修改
|
||||
// see https://developer.work.weixin.qq.com/document/path/95972#%E4%BF%AE%E6%94%B9%E9%97%AE%E7%AD%94
|
||||
func (r *Client) ModKnowledgeIntent(req *ModKnowledgeIntentRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(modKnowledgeIntentURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "ModKnowledgeIntent")
|
||||
}
|
||||
|
||||
// ListKnowledgeIntentRequest 知识库问答列表请求
|
||||
type ListKnowledgeIntentRequest struct {
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
GroupID string `json:"group_id"`
|
||||
IntentID string `json:"intent_id"`
|
||||
}
|
||||
|
||||
// ListKnowledgeIntentResponse 知识库问答列表响应
|
||||
type ListKnowledgeIntentResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
HasMore int `json:"has_more"`
|
||||
IntentList []KnowledgeIntent `json:"intent_list"`
|
||||
}
|
||||
|
||||
// KnowledgeIntent 问答摘要
|
||||
type KnowledgeIntent struct {
|
||||
GroupID string `json:"group_id"`
|
||||
IntentID string `json:"intent_id"`
|
||||
Question IntentQuestion `json:"question"`
|
||||
SimilarQuestions IntentSimilarQuestions `json:"similar_questions"`
|
||||
Answers []IntentAnswerRes `json:"answers"`
|
||||
}
|
||||
|
||||
// IntentAnswerRes 回答返回
|
||||
type IntentAnswerRes struct {
|
||||
Text IntentAnswerText `json:"text"`
|
||||
Attachments []IntentAnswerAttachmentRes `json:"attachments"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentRes 回答附件返回
|
||||
type IntentAnswerAttachmentRes struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
Image IntentAnswerAttachmentImgRes `json:"image,omitempty"`
|
||||
Video IntentAnswerAttachmentVideoRes `json:"video,omitempty"`
|
||||
Link IntentAnswerAttachmentLink `json:"link,omitempty"`
|
||||
MiniProgram IntentAnswerAttachmentMiniProgramRes `json:"miniprogram,omitempty"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentImgRes 图片类型回答附件返回
|
||||
type IntentAnswerAttachmentImgRes struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentVideoRes 视频类型回答附件返回
|
||||
type IntentAnswerAttachmentVideoRes struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// IntentAnswerAttachmentMiniProgramRes 小程序类型回答附件返回
|
||||
type IntentAnswerAttachmentMiniProgramRes struct {
|
||||
Title string `json:"title"`
|
||||
AppID string `json:"appid"`
|
||||
PagePath string `json:"pagepath"`
|
||||
}
|
||||
|
||||
// ListKnowledgeIntent 知识库问答列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/95972#%E8%8E%B7%E5%8F%96%E9%97%AE%E7%AD%94%E5%88%97%E8%A1%A8
|
||||
func (r *Client) ListKnowledgeIntent(req *ListKnowledgeIntentRequest) (*ListKnowledgeIntentResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(listKnowledgeIntentURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListKnowledgeIntentResponse{}
|
||||
err = util.DecodeWithError(response, result, "ListKnowledgeIntent")
|
||||
return result, err
|
||||
}
|
||||
123
work/kf/statistic.go
Normal file
123
work/kf/statistic.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package kf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// getCorpStatisticURL 获取「客户数据统计」企业汇总数据
|
||||
getCorpStatisticURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/get_corp_statistic?access_token=%s"
|
||||
// getServicerStatisticURL 获取「客户数据统计」接待人员明细数据
|
||||
getServicerStatisticURL = "https://qyapi.weixin.qq.com/cgi-bin/kf/get_servicer_statistic?access_token=%s"
|
||||
)
|
||||
|
||||
// GetCorpStatisticRequest 获取「客户数据统计」企业汇总数据请求
|
||||
type GetCorpStatisticRequest struct {
|
||||
OpenKfID string `json:"open_kfid"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
}
|
||||
|
||||
// GetCorpStatisticResponse 获取「客户数据统计」企业汇总数据响应
|
||||
type GetCorpStatisticResponse struct {
|
||||
util.CommonError
|
||||
StatisticList []CorpStatisticList `json:"statistic_list"`
|
||||
}
|
||||
|
||||
// CorpStatisticList 企业汇总统计数据列表
|
||||
type CorpStatisticList struct {
|
||||
StatTime int64 `json:"stat_time"`
|
||||
Statistic CorpStatistic `json:"statistic"`
|
||||
}
|
||||
|
||||
// CorpStatistic 企业汇总统计一天的统计数据
|
||||
type CorpStatistic struct {
|
||||
SessionCnt int64 `json:"session_cnt"`
|
||||
CustomerCnt int64 `json:"customer_cnt"`
|
||||
CustomerMsgCnt int64 `json:"customer_msg_cnt"`
|
||||
UpgradeServiceCustomerCnt int64 `json:"upgrade_service_customer_cnt"`
|
||||
AiSessionReplyCnt int64 `json:"ai_session_reply_cnt"`
|
||||
AiTransferRate float64 `json:"ai_transfer_rate"`
|
||||
AiKnowledgeHitRate float64 `json:"ai_knowledge_hit_rate"`
|
||||
MsgRejectedCustomerCnt int64 `json:"msg_rejected_customer_cnt"`
|
||||
}
|
||||
|
||||
// GetCorpStatistic 获取「客户数据统计」企业汇总数据
|
||||
// see https://developer.work.weixin.qq.com/document/path/95489
|
||||
func (r *Client) GetCorpStatistic(req *GetCorpStatisticRequest) (*GetCorpStatisticResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getCorpStatisticURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetCorpStatisticResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetCorpStatistic")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetServicerStatisticRequest 获取「客户数据统计」接待人员明细数据请求
|
||||
type GetServicerStatisticRequest struct {
|
||||
OpenKfID string `json:"open_kfid"`
|
||||
ServicerUserID string `json:"servicer_userid"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
EndTime int64 `json:"end_time"`
|
||||
}
|
||||
|
||||
// GetServicerStatisticResponse 获取「客户数据统计」接待人员明细数据响应
|
||||
type GetServicerStatisticResponse struct {
|
||||
util.CommonError
|
||||
StatisticList []ServicerStatisticList `json:"statistic_list"`
|
||||
}
|
||||
|
||||
// ServicerStatisticList 接待人员明细统计数据列表
|
||||
type ServicerStatisticList struct {
|
||||
StatTime int64 `json:"stat_time"`
|
||||
Statistic ServicerStatistic `json:"statistic"`
|
||||
}
|
||||
|
||||
// ServicerStatistic 接待人员明细统计一天的统计数据
|
||||
type ServicerStatistic struct {
|
||||
SessionCnt int64 `json:"session_cnt"`
|
||||
CustomerCnt int64 `json:"customer_cnt"`
|
||||
CustomerMsgCnt int64 `json:"customer_msg_cnt"`
|
||||
ReplyRate float64 `json:"reply_rate"`
|
||||
FirstReplyAverageSec float64 `json:"first_reply_average_sec"`
|
||||
SatisfactionInvestgateCnt int64 `json:"satisfaction_investgate_cnt"`
|
||||
SatisfactionParticipationRate float64 `json:"satisfaction_participation_rate"`
|
||||
SatisfiedRate float64 `json:"satisfied_rate"`
|
||||
MiddlingRate float64 `json:"middling_rate"`
|
||||
DissatisfiedRate float64 `json:"dissatisfied_rate"`
|
||||
UpgradeServiceCustomerCnt int64 `json:"upgrade_service_customer_cnt"`
|
||||
UpgradeServiceMemberInviteCnt int64 `json:"upgrade_service_member_invite_cnt"`
|
||||
UpgradeServiceMemberCustomerCnt int64 `json:"upgrade_service_member_customer_cnt"`
|
||||
UpgradeServiceGroupChatInviteCnt int64 `json:"upgrade_service_groupchat_invite_cnt"`
|
||||
UpgradeServiceGroupChatCustomerCnt int64 `json:"upgrade_service_groupchat_customer_cnt"`
|
||||
MsgRejectedCustomerCnt int64 `json:"msg_rejected_customer_cnt"`
|
||||
}
|
||||
|
||||
// GetServicerStatistic 获取「客户数据统计」接待人员明细数据
|
||||
// see https://developer.work.weixin.qq.com/document/path/95490
|
||||
func (r *Client) GetServicerStatistic(req *GetServicerStatisticRequest) (*GetServicerStatisticResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.ctx.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getServicerStatisticURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetServicerStatisticResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetServicerStatistic")
|
||||
return result, err
|
||||
}
|
||||
@@ -16,9 +16,11 @@ const (
|
||||
|
||||
// SyncMsgOptions 获取消息查询参数
|
||||
type SyncMsgOptions struct {
|
||||
Cursor string `json:"cursor"` // 上一次调用时返回的next_cursor,第一次拉取可以不填, 不多于64字节
|
||||
Token string `json:"token"` // 回调事件返回的token字段,10分钟内有效;可不填,如果不填接口有严格的频率限制, 不多于128字节
|
||||
Limit uint `json:"limit"` // 期望请求的数据量,默认值和最大值都为1000, 注意:可能会出现返回条数少于limit的情况,需结合返回的has_more字段判断是否继续请求。
|
||||
Cursor string `json:"cursor"` // 上一次调用时返回的next_cursor,第一次拉取可以不填, 不多于64字节
|
||||
Token string `json:"token"` // 回调事件返回的token字段,10分钟内有效;可不填,如果不填接口有严格的频率限制, 不多于128字节
|
||||
Limit uint `json:"limit"` // 期望请求的数据量,默认值和最大值都为1000, 注意:可能会出现返回条数少于limit的情况,需结合返回的has_more字段判断是否继续请求。
|
||||
VoiceFormat uint `json:"voice_format,omitempty"` // 语音消息类型,0-Amr 1-Silk,默认0。可通过该参数控制返回的语音格式,开发者可按需选择自己程序支持的一种格式
|
||||
OpenKfID string `json:"open_kfid,omitempty"` // 指定拉取某个客服帐号的消息,否则默认返回有权限的客服帐号的消息。当客服帐号较多,建议按open_kfid来拉取以获取更好的性能。
|
||||
}
|
||||
|
||||
// SyncMsgSchema 获取消息查询响应内容
|
||||
|
||||
@@ -7,8 +7,12 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// UploadImgURL 上传图片
|
||||
UploadImgURL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s"
|
||||
// uploadImgURL 上传图片
|
||||
uploadImgURL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s"
|
||||
// uploadTempFile 上传临时素材
|
||||
uploadTempFile = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s"
|
||||
// uploadAttachment 上传附件资源
|
||||
uploadAttachment = "https://qyapi.weixin.qq.com/cgi-bin/media/upload_attachment?access_token=%s&media_type=%s&attachment_type=%d"
|
||||
)
|
||||
|
||||
// UploadImgResponse 上传图片响应
|
||||
@@ -17,6 +21,22 @@ type UploadImgResponse struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// UploadTempFileResponse 上传临时素材响应
|
||||
type UploadTempFileResponse struct {
|
||||
util.CommonError
|
||||
MediaID string `json:"media_id"`
|
||||
CreateAt string `json:"created_at"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// UploadAttachmentResponse 上传资源附件响应
|
||||
type UploadAttachmentResponse struct {
|
||||
util.CommonError
|
||||
MediaID string `json:"media_id"`
|
||||
CreateAt int64 `json:"created_at"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// UploadImg 上传图片
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90256
|
||||
func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
|
||||
@@ -28,12 +48,51 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostFile("media", filename, fmt.Sprintf(UploadImgURL, accessToken)); err != nil {
|
||||
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 {
|
||||
err = util.DecodeWithError(response, result, "UploadImg")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UploadTempFile 上传临时素材
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90253
|
||||
// @mediaType 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
|
||||
func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempFileResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
var response []byte
|
||||
if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UploadTempFileResponse{}
|
||||
err = util.DecodeWithError(response, result, "UploadTempFile")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// UploadAttachment 上传附件资源
|
||||
// @see https://developer.work.weixin.qq.com/document/path/95098
|
||||
// @mediaType 媒体文件类型,分别有图片(image)、视频(video)、普通文件(file)
|
||||
// @attachment_type 附件类型,不同的附件类型用于不同的场景。1:朋友圈;2:商品图册
|
||||
func (r *Client) UploadAttachment(filename string, mediaType string, attachmentType int) (*UploadAttachmentResponse, 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(uploadAttachment, accessToken, mediaType, attachmentType)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UploadAttachmentResponse{}
|
||||
err = util.DecodeWithError(response, result, "UploadAttachment")
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// Package message 消息推送,实现企业微信消息推送相关接口:https://developer.work.weixin.qq.com/document/path/90235
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/work/context"
|
||||
)
|
||||
|
||||
// Client 应用消息
|
||||
// Client 消息推送接口实例
|
||||
type Client struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewClient 实例化
|
||||
// NewClient 初始化实例
|
||||
func NewClient(ctx *context.Context) *Client {
|
||||
return &Client{
|
||||
ctx,
|
||||
}
|
||||
return &Client{ctx}
|
||||
}
|
||||
|
||||
@@ -1,285 +1,130 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/officialaccount/device"
|
||||
)
|
||||
|
||||
// MsgType 企业微信普通消息类型
|
||||
type MsgType string
|
||||
|
||||
// EventType 企业微信事件消息类型
|
||||
type EventType string
|
||||
|
||||
// InfoType 第三方平台授权事件类型
|
||||
type InfoType string
|
||||
|
||||
const (
|
||||
//MsgTypeEvent 表示事件推送消息 [限接收]
|
||||
MsgTypeEvent = "event"
|
||||
|
||||
//MsgTypeText 表示文本消息
|
||||
MsgTypeText MsgType = "text"
|
||||
//MsgTypeImage 表示图片消息
|
||||
MsgTypeImage MsgType = "image"
|
||||
//MsgTypeVoice 表示语音消息
|
||||
MsgTypeVoice MsgType = "voice"
|
||||
//MsgTypeVideo 表示视频消息
|
||||
MsgTypeVideo MsgType = "video"
|
||||
//MsgTypeNews 表示图文消息[限回复与发送应用消息]
|
||||
MsgTypeNews MsgType = "news"
|
||||
|
||||
//MsgTypeLink 表示链接消息[限接收]
|
||||
MsgTypeLink MsgType = "link"
|
||||
//MsgTypeLocation 表示坐标消息[限接收]
|
||||
MsgTypeLocation MsgType = "location"
|
||||
|
||||
//MsgTypeUpdateButton 更新点击用户的按钮文案[限回复应用消息]
|
||||
MsgTypeUpdateButton MsgType = "update_button"
|
||||
//MsgTypeUpdateTemplateCard 更新点击用户的整张卡片[限回复应用消息]
|
||||
MsgTypeUpdateTemplateCard MsgType = "update_template_card"
|
||||
|
||||
//MsgTypeFile 文件消息[限发送应用消息]
|
||||
MsgTypeFile MsgType = "file"
|
||||
//MsgTypeTextCard 文本卡片消息[限发送应用消息]
|
||||
MsgTypeTextCard MsgType = "textcard"
|
||||
//MsgTypeMpNews 图文消息[限发送应用消息] 跟普通的图文消息一致,唯一的差异是图文内容存储在企业微信
|
||||
MsgTypeMpNews MsgType = "mpnews"
|
||||
//MsgTypeMarkdown markdown消息[限发送应用消息]
|
||||
MsgTypeMarkdown MsgType = "markdown"
|
||||
//MsgTypeMiniprogramNotice 小程序通知消息[限发送应用消息]
|
||||
MsgTypeMiniprogramNotice MsgType = "miniprogram_notice"
|
||||
//MsgTypeTemplateCard 模板卡片消息[限发送应用消息]
|
||||
MsgTypeTemplateCard MsgType = "template_card"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
//EventSubscribe 成员关注,成员已经加入企业,管理员添加成员到应用可见范围(或移除可见范围)时
|
||||
EventSubscribe EventType = "subscribe"
|
||||
//EventUnsubscribe 成员取消关注,成员已经在应用可见范围,成员加入(或退出)企业时
|
||||
EventUnsubscribe EventType = "unsubscribe"
|
||||
//EventEnterAgent 本事件在成员进入企业微信的应用时触发
|
||||
EventEnterAgent EventType = "enter_agent"
|
||||
//EventLocation 上报地理位置事件
|
||||
EventLocation EventType = "LOCATION"
|
||||
//EventBatchJobResult 异步任务完成事件推送
|
||||
EventBatchJobResult EventType = "batch_job_result"
|
||||
//EventClick 点击菜单拉取消息时的事件推送
|
||||
EventClick EventType = "click"
|
||||
//EventView 点击菜单跳转链接时的事件推送
|
||||
EventView EventType = "view"
|
||||
//EventScancodePush 扫码推事件的事件推送
|
||||
EventScancodePush EventType = "scancode_push"
|
||||
//EventScancodeWaitmsg 扫码推事件且弹出“消息接收中”提示框的事件推送
|
||||
EventScancodeWaitmsg EventType = "scancode_waitmsg"
|
||||
//EventPicSysphoto 弹出系统拍照发图的事件推送
|
||||
EventPicSysphoto EventType = "pic_sysphoto"
|
||||
//EventPicPhotoOrAlbum 弹出拍照或者相册发图的事件推送
|
||||
EventPicPhotoOrAlbum EventType = "pic_photo_or_album"
|
||||
//EventPicWeixin 弹出微信相册发图器的事件推送
|
||||
EventPicWeixin EventType = "pic_weixin"
|
||||
//EventLocationSelect 弹出地理位置选择器的事件推送
|
||||
EventLocationSelect EventType = "location_select"
|
||||
|
||||
//EventOpenApprovalChange 审批状态通知事件推送
|
||||
EventOpenApprovalChange EventType = "open_approval_change"
|
||||
|
||||
//EventShareAgentChange 共享应用事件回调
|
||||
EventShareAgentChange EventType = "share_agent_change"
|
||||
|
||||
//EventTemplateCard 模板卡片事件推送
|
||||
EventTemplateCard EventType = "template_card_event"
|
||||
|
||||
//EventTemplateCardMenu 通用模板卡片右上角菜单事件推送
|
||||
EventTemplateCardMenu EventType = "template_card_menu_event"
|
||||
|
||||
//EventChangeExternalContact 企业客户事件推送
|
||||
//add_external_contact 添加
|
||||
//edit_external_contact 编辑
|
||||
//add_half_external_contact 免验证添加
|
||||
//del_external_contact 员工删除客户
|
||||
//del_follow_user 客户删除跟进员工
|
||||
//transfer_fail 企业将客户分配给新的成员接替后,客户添加失败
|
||||
//change_external_chat 客户群创建事件
|
||||
EventChangeExternalContact EventType = "change_external_contact"
|
||||
|
||||
//EventChangeExternalChat 企业客户群变更事件推送
|
||||
//create 客户群创建
|
||||
//update 客户群变更
|
||||
//dismiss 客户群解散
|
||||
EventChangeExternalChat EventType = "change_external_chat"
|
||||
|
||||
//EventChangeExternalTag 企业客户标签创建事件推送
|
||||
//create 创建标签
|
||||
//update 变更标签
|
||||
//delete 删除标签
|
||||
//shuffle 重新排序
|
||||
EventChangeExternalTag EventType = "change_external_tag"
|
||||
|
||||
//EventKfMsg 企业微信客服回调事件
|
||||
EventKfMsg EventType = "kf_msg_or_event"
|
||||
//EventLivingStatusChange 直播回调事件
|
||||
EventLivingStatusChange EventType = "living_status_change"
|
||||
|
||||
//EventMsgauditNotify 会话内容存档开启后,产生会话回调事件
|
||||
EventMsgauditNotify EventType = "msgaudit_notify"
|
||||
// 发送应用消息的接口地址
|
||||
sendURL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s"
|
||||
)
|
||||
|
||||
//todo 第三方应用开发
|
||||
/*const (
|
||||
//微信开放平台需要用到
|
||||
type (
|
||||
// SendRequestCommon 发送应用消息请求公共参数
|
||||
SendRequestCommon struct {
|
||||
// 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。 特殊情况:指定为"@all",则向该企业应用的全部成员发送
|
||||
ToUser string `json:"touser"`
|
||||
// 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为"@all"时忽略本参数
|
||||
ToParty string `json:"toparty"`
|
||||
// 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为"@all"时忽略本参数
|
||||
ToTag string `json:"totag"`
|
||||
// 消息类型,此时固定为:text
|
||||
MsgType string `json:"msgtype"`
|
||||
// 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
|
||||
AgentID string `json:"agentid"`
|
||||
// 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
|
||||
Safe int `json:"safe"`
|
||||
// 表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。
|
||||
EnableIDTrans int `json:"enable_id_trans"`
|
||||
// 表示是否开启重复消息检查,0表示否,1表示是,默认0
|
||||
EnableDuplicateCheck int `json:"enable_duplicate_check"`
|
||||
// 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
|
||||
DuplicateCheckInterval int `json:"duplicate_check_interval"`
|
||||
}
|
||||
// SendResponse 发送应用消息响应参数
|
||||
SendResponse struct {
|
||||
util.CommonError
|
||||
InvalidUser string `json:"invaliduser"` // 不合法的userid,不区分大小写,统一转为小写
|
||||
InvalidParty string `json:"invalidparty"` // 不合法的partyid
|
||||
InvalidTag string `json:"invalidtag"` // 不合法的标签id
|
||||
UnlicensedUser string `json:"unlicenseduser"` // 没有基础接口许可(包含已过期)的userid
|
||||
MsgID string `json:"msgid"` // 消息id
|
||||
ResponseCode string `json:"response_code"`
|
||||
}
|
||||
|
||||
// InfoTypeVerifyTicket 返回ticket
|
||||
InfoTypeVerifyTicket InfoType = "component_verify_ticket"
|
||||
// InfoTypeAuthorized 授权
|
||||
InfoTypeAuthorized = "authorized"
|
||||
// InfoTypeUnauthorized 取消授权
|
||||
InfoTypeUnauthorized = "unauthorized"
|
||||
// InfoTypeUpdateAuthorized 更新授权
|
||||
InfoTypeUpdateAuthorized = "updateauthorized"
|
||||
)*/
|
||||
// SendTextRequest 发送文本消息的请求
|
||||
SendTextRequest struct {
|
||||
*SendRequestCommon
|
||||
Text TextField `json:"text"`
|
||||
}
|
||||
// TextField 文本消息参数
|
||||
TextField struct {
|
||||
// 消息内容,最长不超过2048个字节,超过将截断(支持id转译)
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
//MixMessage 存放所有企业微信官方发送过来的消息和事件
|
||||
type MixMessage struct {
|
||||
CommonToken
|
||||
// SendImageRequest 发送图片消息的请求
|
||||
SendImageRequest struct {
|
||||
*SendRequestCommon
|
||||
Image ImageField `json:"image"`
|
||||
}
|
||||
// ImageField 图片消息参数
|
||||
ImageField struct {
|
||||
// 图片媒体文件id,可以调用上传临时素材接口获取
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
//接收普通消息
|
||||
MsgID int64 `xml:"MsgId"` //其他消息推送过来是MsgId
|
||||
AgentID int `xml:"AgentID"` //企业应用的id,整型。可在应用的设置页面查看
|
||||
// SendVoiceRequest 发送语音消息的请求
|
||||
SendVoiceRequest struct {
|
||||
*SendRequestCommon
|
||||
Voice VoiceField `json:"voice"`
|
||||
}
|
||||
// VoiceField 语音消息参数
|
||||
VoiceField struct {
|
||||
// 语音文件id,可以调用上传临时素材接口获取
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
)
|
||||
|
||||
Content string `xml:"Content,omitempty"` //文本消息内容
|
||||
Format string `xml:"Format,omitempty"` //语音消息格式,如amr,speex等
|
||||
ThumbMediaID string `xml:"ThumbMediaId,omitempty"` //视频消息缩略图的媒体id,可以调用获取媒体文件接口拉取数据,仅三天内有效
|
||||
|
||||
Title string `xml:"Title,omitempty"` //链接消息,标题
|
||||
Description string `xml:"Description,omitempty"` //链接消息,描述
|
||||
URL string `xml:"Url,omitempty"` //链接消息,链接跳转的url
|
||||
|
||||
PicURL string `xml:"PicUrl,omitempty"` ////图片消息或者链接消息,封面缩略图的url
|
||||
MediaID string `xml:"MediaId,omitempty"` //图片媒体文件id//语音媒体文件id//视频消息缩略图的媒体id,可以调用获取媒体文件接口拉取,仅三天内有效
|
||||
|
||||
LocationX float64 `xml:"Location_X,omitempty"` //位置消息,地理位置纬度
|
||||
LocationY float64 `xml:"Location_Y,omitempty"` //位置消息,地理位置经度
|
||||
Scale float64 `xml:"Scale,omitempty"` //位置消息,地图缩放大小
|
||||
Label string `xml:"Label,omitempty"` //位置消息,地理位置信息
|
||||
|
||||
AppType string `xml:"AppType,omitempty"` //接收地理位置时存在,app类型,在企业微信固定返回wxwork,在微信不返回该字段
|
||||
|
||||
//TemplateMsgID int64 `xml:"MsgID"` //模板消息推送成功的消息是MsgID
|
||||
///Recognition string `xml:"Recognition"`
|
||||
|
||||
//事件相关
|
||||
Event EventType `xml:"Event,omitempty"`
|
||||
EventKey string `xml:"EventKey,omitempty"`
|
||||
ChangeType string `xml:"ChangeType,omitempty"`
|
||||
|
||||
//模板卡片事件推送 https://developer.work.weixin.qq.com/document/path/90240#%E6%A8%A1%E6%9D%BF%E5%8D%A1%E7%89%87%E4%BA%8B%E4%BB%B6%E6%8E%A8%E9%80%81
|
||||
TaskId string `xml:"TaskId,omitempty"` //与发送模板卡片消息时指定的task_id相同
|
||||
CardType string `xml:"CardType,omitempty"` //通用模板卡片的类型,类型有"text_notice", "news_notice", "button_interaction", "vote_interaction", "multiple_interaction"五种
|
||||
ResponseCode string `xml:"ResponseCode,omitempty"` //用于调用更新卡片接口的ResponseCode,24小时内有效,且只能使用一次
|
||||
SelectedItems struct {
|
||||
SelectedItem struct {
|
||||
QuestionKey string `xml:"QuestionKey"` //问题的key值
|
||||
OptionIds struct { //对应问题的选项列表
|
||||
OptionId string `xml:"OptionId"`
|
||||
} `xml:"OptionIds"`
|
||||
} `xml:"SelectedItem"`
|
||||
} `xml:"SelectedItems,omitempty"`
|
||||
|
||||
//仅上报地理位置事件
|
||||
Latitude string `xml:"Latitude,omitempty"` //地理位置纬度
|
||||
Longitude string `xml:"Longitude,omitempty"` //地理位置经度
|
||||
Precision string `xml:"Precision,omitempty"` //地理位置精度
|
||||
|
||||
//仅异步任务完成事件
|
||||
JobId string `xml:"JobId,omitempty"` //异步任务id,最大长度为64字符
|
||||
JobType string `xml:"JobType,omitempty"` //异步任务,操作类型,字符串,目前分别有:sync_user(增量更新成员)、 replace_user(全量覆盖成员)、invite_user(邀请成员关注)、replace_party(全量覆盖部门)
|
||||
ErrCode int `xml:"ErrCode,omitempty"` //异步任务,返回码
|
||||
ErrMsg string `xml:"ErrMsg,omitempty"` //异步任务,对返回码的文本描述内容
|
||||
|
||||
//开启通讯录回调通知 https://open.work.weixin.qq.com/api/doc/90000/90135/90967
|
||||
UserID string `xml:"UserID,omitempty"` //用户userid
|
||||
ExternalUserID string `xml:"ExternalUserID,omitempty"` //外部联系人userid
|
||||
State string `xml:"State,omitempty"` //添加此用户的「联系我」方式配置的state参数,可用于识别添加此用户的渠道
|
||||
WelcomeCode string `xml:"WelcomeCode,omitempty"` //欢迎码,当state为1时,该值有效
|
||||
Source string `xml:"Source,omitempty"` //删除客户的操作来源,DELETE_BY_TRANSFER表示此客户是因在职继承自动被转接成员删除
|
||||
|
||||
// todo 第三方平台相关 字段名可能不准确
|
||||
/*InfoType InfoType `xml:"InfoType"`
|
||||
AppID string `xml:"AppId"`
|
||||
ComponentVerifyTicket string `xml:"ComponentVerifyTicket"`
|
||||
AuthorizerAppid string `xml:"AuthorizerAppid"`
|
||||
AuthorizationCode string `xml:"AuthorizationCode"```````````````````````````````````````
|
||||
AuthorizationCodeExpiredTime int64 `xml:"AuthorizationCodeExpiredTime"`
|
||||
PreAuthCode string `xml:"PreAuthCode"`*/
|
||||
|
||||
//设备相关
|
||||
device.MsgDevice
|
||||
// Send 发送应用消息
|
||||
// @desc 实现企业微信发送应用消息接口:https://developer.work.weixin.qq.com/document/path/90236
|
||||
func (r *Client) Send(apiName string, request interface{}) (*SendResponse, error) {
|
||||
// 获取accessToken
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 请求参数转 JSON 格式
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 发起http请求
|
||||
response, err := util.HTTPPost(fmt.Sprintf(sendURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 按照结构体解析返回值
|
||||
result := &SendResponse{}
|
||||
err = util.DecodeWithError(response, result, apiName)
|
||||
// 返回数据
|
||||
return result, err
|
||||
}
|
||||
|
||||
//EventPic 发图事件推送
|
||||
type EventPic struct {
|
||||
PicMd5Sum string `xml:"PicMd5Sum"`
|
||||
// SendText 发送文本消息
|
||||
func (r *Client) SendText(request SendTextRequest) (*SendResponse, error) {
|
||||
// 发送文本消息MsgType参数固定为:text
|
||||
request.MsgType = "text"
|
||||
return r.Send("MessageSendText", request)
|
||||
}
|
||||
|
||||
//EncryptedXMLMsg 安全模式下的消息体
|
||||
type EncryptedXMLMsg struct {
|
||||
XMLName struct{} `xml:"xml" json:"-"`
|
||||
ToUserName string `xml:"ToUserName" json:"ToUserName"`
|
||||
AgentID string `xml:"AgentID" json:"AgentID"`
|
||||
EncryptedMsg string `xml:"Encrypt" json:"Encrypt"`
|
||||
// SendImage 发送图片消息
|
||||
func (r *Client) SendImage(request SendImageRequest) (*SendResponse, error) {
|
||||
// 发送图片消息MsgType参数固定为:image
|
||||
request.MsgType = "image"
|
||||
return r.Send("MessageSendImage", request)
|
||||
}
|
||||
|
||||
//ResponseEncryptedXMLMsg 需要返回的消息体
|
||||
type ResponseEncryptedXMLMsg struct {
|
||||
XMLName struct{} `xml:"xml" json:"-"`
|
||||
EncryptedMsg string `xml:"Encrypt" json:"Encrypt"`
|
||||
MsgSignature string `xml:"MsgSignature" json:"MsgSignature"`
|
||||
Timestamp int64 `xml:"TimeStamp" json:"TimeStamp"`
|
||||
Nonce string `xml:"Nonce" json:"Nonce"`
|
||||
// SendVoice 发送语音消息
|
||||
func (r *Client) SendVoice(request SendVoiceRequest) (*SendResponse, error) {
|
||||
// 发送语音消息MsgType参数固定为:voice
|
||||
request.MsgType = "voice"
|
||||
return r.Send("MessageSendVoice", request)
|
||||
}
|
||||
|
||||
// CDATA 使用该类型,在序列化为 xml 文本时文本会被解析器忽略
|
||||
type CDATA string
|
||||
|
||||
// MarshalXML 实现自己的序列化方法
|
||||
func (c CDATA) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
return e.EncodeElement(struct {
|
||||
string `xml:",cdata"`
|
||||
}{string(c)}, start)
|
||||
}
|
||||
|
||||
// CommonToken 消息中通用的结构
|
||||
type CommonToken struct {
|
||||
XMLName xml.Name `xml:"xml"`
|
||||
ToUserName CDATA `xml:"ToUserName"`
|
||||
FromUserName CDATA `xml:"FromUserName"`
|
||||
CreateTime int64 `xml:"CreateTime"`
|
||||
MsgType MsgType `xml:"MsgType"`
|
||||
}
|
||||
|
||||
//SetToUserName set ToUserName
|
||||
func (msg *CommonToken) SetToUserName(toUserName CDATA) {
|
||||
msg.ToUserName = toUserName
|
||||
}
|
||||
|
||||
//SetFromUserName set FromUserName
|
||||
func (msg *CommonToken) SetFromUserName(fromUserName CDATA) {
|
||||
msg.FromUserName = fromUserName
|
||||
}
|
||||
|
||||
//SetCreateTime set createTime
|
||||
func (msg *CommonToken) SetCreateTime(createTime int64) {
|
||||
msg.CreateTime = createTime
|
||||
}
|
||||
|
||||
//SetMsgType set MsgType
|
||||
func (msg *CommonToken) SetMsgType(msgType MsgType) {
|
||||
msg.MsgType = msgType
|
||||
}
|
||||
|
||||
//GetOpenID get the FromUserName value
|
||||
func (msg *CommonToken) GetOpenID() string {
|
||||
return string(msg.FromUserName)
|
||||
}
|
||||
// 以上实现了部分常用消息推送:SendText 发送文本消息、SendImage 发送图片消息、SendVoice 发送语音消息,
|
||||
// 如需扩展其他消息类型,建议按照以上格式,扩展对应消息类型的参数即可
|
||||
// 也可以直接使用Send方法,按照企业微信消息推送的接口文档传对应消息类型的参数来使用
|
||||
|
||||
@@ -149,10 +149,7 @@ func (s *Client) GetRawChatData(seq uint64, limit uint64, proxy string, passwd s
|
||||
|
||||
var data ChatDataResponse
|
||||
err := json.Unmarshal(buf, &data)
|
||||
if err != nil {
|
||||
return ChatDataResponse{}, err
|
||||
}
|
||||
return data, nil
|
||||
return data, err
|
||||
}
|
||||
|
||||
// DecryptData 解析密文.企业微信自有解密内容
|
||||
|
||||
@@ -150,7 +150,7 @@ type TodoMessage struct {
|
||||
BaseMessage
|
||||
Todo struct {
|
||||
Title string `json:"title,omitempty"` // 代办的来源文本
|
||||
Content string `json:"content,omitempty"` // 代办的具体内容
|
||||
Content string `json:"content,omitempty"` // 代办的具体内容
|
||||
} `json:"todo,omitempty"`
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ type CollectMessage struct {
|
||||
Collect struct {
|
||||
RoomName string `json:"room_name,omitempty"` // 填表消息所在的群名称。
|
||||
Creator string `json:"creator,omitempty"` // 创建者在群中的名字
|
||||
CreateTime string `json:"create_time,omitempty"` // 创建的时间
|
||||
CreateTime int64 `json:"create_time,omitempty"` // 创建的时间
|
||||
Details []CollectDetails `json:"details,omitempty"` // 表内容
|
||||
} `json:"collect,omitempty"`
|
||||
}
|
||||
@@ -266,10 +266,10 @@ type VoipDocShareMessage struct {
|
||||
type ExternalRedPacketMessage struct {
|
||||
BaseMessage
|
||||
RedPacket struct {
|
||||
Type int32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||
Wish int32 `json:"wish,omitempty"` // 红包祝福语。String类型
|
||||
TotalCnt int32 `json:"totalcnt,omitempty"` // 红包总个数。Uint32类型
|
||||
TotalAmount int32 `json:"totalamount,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||
Type uint32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||
Wish string `json:"wish,omitempty"` // 红包祝福语。String类型
|
||||
TotalCnt uint32 `json:"totalcnt,omitempty"` // 红包总个数。Uint32类型
|
||||
TotalAmount uint32 `json:"totalamount,omitempty"` // 红包总金额。Uint32类型,单位为分。
|
||||
} `json:"redpacket,omitempty"`
|
||||
}
|
||||
|
||||
@@ -277,9 +277,9 @@ type ExternalRedPacketMessage struct {
|
||||
type SphFeedMessage struct {
|
||||
BaseMessage
|
||||
SphFeed struct {
|
||||
FeedType string `json:"feed_type,omitempty"` // 视频号消息类型
|
||||
SphName string `json:"sph_name,omitempty"` // 视频号账号名称
|
||||
FeedDesc uint64 `json:"feed_desc,omitempty"` // 视频号账号名称
|
||||
FeedType uint32 `json:"feed_type,omitempty"` // 视频号消息类型。2 图片、4 视频、9 直播。Uint32类型
|
||||
SphName string `json:"sph_name,omitempty"` // 视频号账号名称。String类型
|
||||
FeedDesc string `json:"feed_desc,omitempty"` // 视频号消息描述。String类型
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@ var (
|
||||
oauthUserInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s"
|
||||
// oauthQrContentTargetURL 构造独立窗口登录二维码
|
||||
oauthQrContentTargetURL = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&redirect_uri=%s&state=%s"
|
||||
//code2Session 获取用户信息地址
|
||||
code2SessionURL = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token=%s&js_code=%s&grant_type=authorization_code"
|
||||
// getUserInfoURL 获取访问用户身份&获取用户登录身份
|
||||
getUserInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s"
|
||||
// getUserDetailURL 获取访问用户敏感信息
|
||||
getUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=%s"
|
||||
)
|
||||
|
||||
// NewOauth new init oauth
|
||||
@@ -76,7 +78,6 @@ type ResUserInfo struct {
|
||||
// 非企业成员授权时返回
|
||||
OpenID string `json:"OpenId"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
UserTicket string `json:"user_ticket"`
|
||||
}
|
||||
|
||||
// UserFromCode 根据code获取用户信息
|
||||
@@ -97,23 +98,68 @@ func (ctr *Oauth) UserFromCode(code string) (result ResUserInfo, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (ctr *Oauth) Code2Session(code string) (result ResUserInfo, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = ctr.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
// GetUserInfoResponse 获取访问用户身份&获取用户登录身份响应
|
||||
type GetUserInfoResponse struct {
|
||||
util.CommonError
|
||||
UserID string `json:"userid"`
|
||||
UserTicket string `json:"user_ticket"`
|
||||
OpenID string `json:"openid"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
}
|
||||
|
||||
// GetUserInfo 获取访问用户身份&获取用户登录身份
|
||||
// @see https://developer.work.weixin.qq.com/document/path/90213 获取访问用户身份
|
||||
// @see https://developer.work.weixin.qq.com/document/path/98176 获取用户登录身份
|
||||
func (ctr *Oauth) GetUserInfo(code string) (*GetUserInfoResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = ctr.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.HTTPGet(
|
||||
fmt.Sprintf(code2SessionURL, accessToken, code),
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
if response, err = util.HTTPGet(fmt.Sprintf(getUserInfoURL, accessToken, code)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(response, &result)
|
||||
if result.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetUserAccessToken error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
result := &GetUserInfoResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetUserInfo")
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetUserDetailRequest 获取访问用户敏感信息请求
|
||||
type GetUserDetailRequest struct {
|
||||
UserTicket string `json:"user_ticket"`
|
||||
}
|
||||
|
||||
// GetUserDetailResponse 获取访问用户敏感信息响应
|
||||
type GetUserDetailResponse struct {
|
||||
util.CommonError
|
||||
UserID string `json:"userid"`
|
||||
Gender string `json:"gender"`
|
||||
Avatar string `json:"avatar"`
|
||||
QrCode string `json:"qr_code"`
|
||||
Mobile string `json:"mobile"`
|
||||
Email string `json:"email"`
|
||||
BizMail string `json:"biz_mail"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
// GetUserDetail 获取访问用户敏感信息
|
||||
// @see https://developer.work.weixin.qq.com/document/path/95833
|
||||
func (ctr *Oauth) GetUserDetail(req *GetUserDetailRequest) (*GetUserDetailResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = ctr.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(getUserDetailURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetUserDetailResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetUserDetail")
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -8,15 +8,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// WebhookSendURL 机器人发送群组消息
|
||||
WebhookSendURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s"
|
||||
// webhookSendURL 机器人发送群组消息
|
||||
webhookSendURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s"
|
||||
)
|
||||
|
||||
// RobotBroadcast 群机器人消息发送
|
||||
// @see https://developer.work.weixin.qq.com/document/path/91770
|
||||
func (r *Client) RobotBroadcast(webhookKey string, options interface{}) (info util.CommonError, err error) {
|
||||
var data []byte
|
||||
if data, err = util.PostJSON(fmt.Sprintf(WebhookSendURL, webhookKey), options); err != nil {
|
||||
if data, err = util.PostJSON(fmt.Sprintf(webhookSendURL, webhookKey), options); err != nil {
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(data, &info); err != nil {
|
||||
|
||||
58
work/work.go
58
work/work.go
@@ -3,20 +3,18 @@ package work
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/credential"
|
||||
"github.com/silenceper/wechat/v2/work/addresslist"
|
||||
"github.com/silenceper/wechat/v2/work/appchat"
|
||||
"github.com/silenceper/wechat/v2/work/checkin"
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
"github.com/silenceper/wechat/v2/work/context"
|
||||
"github.com/silenceper/wechat/v2/work/externalcontact"
|
||||
"github.com/silenceper/wechat/v2/work/js"
|
||||
"github.com/silenceper/wechat/v2/work/invoice"
|
||||
"github.com/silenceper/wechat/v2/work/kf"
|
||||
"github.com/silenceper/wechat/v2/work/material"
|
||||
"github.com/silenceper/wechat/v2/work/message"
|
||||
"github.com/silenceper/wechat/v2/work/msgaudit"
|
||||
"github.com/silenceper/wechat/v2/work/oauth"
|
||||
"github.com/silenceper/wechat/v2/work/robot"
|
||||
"github.com/silenceper/wechat/v2/work/server"
|
||||
"github.com/silenceper/wechat/v2/work/tools"
|
||||
"github.com/silenceper/wechat/v2/work/user"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Work 企业微信
|
||||
@@ -39,24 +37,11 @@ func (wk *Work) GetContext() *context.Context {
|
||||
return wk.ctx
|
||||
}
|
||||
|
||||
// GetServer 消息管理:接收事件,被动回复消息管理
|
||||
func (wk *Work) GetServer(req *http.Request, writer http.ResponseWriter) *server.Server {
|
||||
srv := server.NewServer(wk.ctx)
|
||||
srv.Request = req
|
||||
srv.Writer = writer
|
||||
return srv
|
||||
}
|
||||
|
||||
// GetOauth get oauth
|
||||
func (wk *Work) GetOauth() *oauth.Oauth {
|
||||
return oauth.NewOauth(wk.ctx)
|
||||
}
|
||||
|
||||
// GetJs js-sdk配置
|
||||
func (wk *Work) GetJs() *js.Js {
|
||||
return js.NewJs(wk.ctx)
|
||||
}
|
||||
|
||||
// GetMsgAudit get msgAudit
|
||||
func (wk *Work) GetMsgAudit() (*msgaudit.Client, error) {
|
||||
return msgaudit.NewClient(wk.ctx.Config)
|
||||
@@ -67,26 +52,11 @@ func (wk *Work) GetKF() (*kf.Client, error) {
|
||||
return kf.NewClient(wk.ctx.Config)
|
||||
}
|
||||
|
||||
// GetUser get user
|
||||
func (wk *Work) GetUser() *user.User {
|
||||
return user.NewUser(wk.ctx)
|
||||
}
|
||||
|
||||
// GetCalendar get calendar
|
||||
func (wk *Work) GetCalendar() *tools.Calendar {
|
||||
return tools.NewCalendar(wk.ctx)
|
||||
}
|
||||
|
||||
// GetExternalContact 客户联系
|
||||
// GetExternalContact get external_contact
|
||||
func (wk *Work) GetExternalContact() *externalcontact.Client {
|
||||
return externalcontact.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetMessageApp 发送应用消息
|
||||
func (wk *Work) GetMessageApp() *message.Client {
|
||||
return message.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetAddressList get address_list
|
||||
func (wk *Work) GetAddressList() *addresslist.Client {
|
||||
return addresslist.NewClient(wk.ctx)
|
||||
@@ -101,3 +71,23 @@ func (wk *Work) GetMaterial() *material.Client {
|
||||
func (wk *Work) GetRobot() *robot.Client {
|
||||
return robot.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetMessage 获取发送应用消息接口实例
|
||||
func (wk *Work) GetMessage() *message.Client {
|
||||
return message.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetAppChat 获取应用发送消息到群聊会话接口实例
|
||||
func (wk *Work) GetAppChat() *appchat.Client {
|
||||
return appchat.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetInvoice get invoice
|
||||
func (wk *Work) GetInvoice() *invoice.Client {
|
||||
return invoice.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
// GetCheckin 获取打卡接口实例
|
||||
func (wk *Work) GetCheckin() *checkin.Client {
|
||||
return checkin.NewClient(wk.ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user