1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-23 13:42:25 +08:00

Compare commits

..

14 Commits

Author SHA1 Message Date
Phil Holzer
d87f30e5e0 Merge c2a8533781 into 7df3fe1a09 2023-08-16 16:16:41 +08:00
markwang
7df3fe1a09 feat:企业微信-客户联系-客户朋友圈 (#702)
* feat:企业微信-客户联系-客户朋友圈

* fix:golangci-lint

---------

Co-authored-by: markwang <www.wang61@qq.com>
2023-07-31 19:32:34 +08:00
markwang
5a23c5c780 feat:企业微信-客户联系-在职继承/离职继承 (#699)
Co-authored-by: markwang <www.wang61@qq.com>
2023-07-15 23:58:24 +08:00
黄翠刚
c84eb7b550 新增获取部门列表接口:https://qyapi.weixin.qq.com/cgi-bin/department/list (#698) 2023-07-15 23:56:53 +08:00
ourines
45ad2ab8ca 调整结构体中CreateTime (#691)
* fix: 修改FollowInfo结构体中的tag标签为createtime

* fix: 统一CreateTime为int64

* chore: format

* chore: format
2023-06-30 09:54:12 +08:00
txws
5d0e32e2ea 微信开放平台 消息与事件url 添加result_info (#696)
* add result_info

* edit result_info

* edit-01 result_info

* 开放平台message添加小程序名称审核字段
2023-06-30 09:53:01 +08:00
markwang
822cfaa6c8 feat:企业微信-身份验证-获取用户身份及敏感信息 (#692)
Co-authored-by: markwang <www.wang61@qq.com>
2023-06-30 09:52:44 +08:00
markwang
acaab64fe7 feat:企业微信-客户联系-规则组/规则组标签 (#697)
Co-authored-by: markwang <www.wang61@qq.com>
2023-06-30 09:51:36 +08:00
markwang
b12825f83b feat:企业微信-电子发票 (#695)
Co-authored-by: markwang <www.wang61@qq.com>
2023-06-21 17:31:08 +08:00
okhowang
86cbd8c0b2 feat: 微信回调消息增加菜单ID字段 (#694)
close #693
2023-06-16 18:07:15 +08:00
markwang
46c3722308 feat:企业微信-通讯录管理-互联企业 (#688) 2023-06-12 13:34:56 +08:00
houseme
7d11af713b feat: improve workflows config and upgrade action version (#690) 2023-06-11 12:08:38 +08:00
silenceper
fafb1784da Update go.yml: 指定golangci-lint 版本为v1.52.2 (#689) 2023-06-09 20:35:49 +08:00
braumye
c2a8533781 开放平台修改小程序基础信息 2023-01-17 18:47:08 +08:00
23 changed files with 2325 additions and 26 deletions

View File

@@ -10,17 +10,21 @@ jobs:
golangci: golangci:
strategy: strategy:
matrix: matrix:
go-version: [1.16.x,1.17.x,1.18.x] go-version: [ '1.16','1.17','1.18','1.19','1.20' ]
name: golangci-lint name: golangci-lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/setup-go@v3 - name: Setup Golang ${{ matrix.go-version }}
- uses: actions/checkout@v3 uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Checkout
uses: actions/checkout@v3
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v3.2.0 uses: golangci/golangci-lint-action@v3
with: with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: latest version: v1.52.2
build: build:
name: Test name: Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -28,7 +32,7 @@ jobs:
redis: redis:
image: redis image: redis
ports: ports:
- 6379:6379 - 6379:6379
options: --entrypoint redis-server options: --entrypoint redis-server
memcached: memcached:
image: memcached image: memcached
@@ -38,14 +42,14 @@ jobs:
# strategy set # strategy set
strategy: strategy:
matrix: matrix:
go: ["1.16", "1.17", "1.18"] go: [ '1.16','1.17','1.18','1.19','1.20' ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Go 1.x - name: Set up Go 1.x
uses: actions/setup-go@v2 uses: actions/setup-go@v4
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
id: go id: go
- name: Test - name: Test
run: go test -v -race ./... run: go test -v -race ./...

View File

@@ -11,17 +11,17 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- -
name: Set up Go name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v4
with: with:
go-version: 1.15 go-version: 1.16
- -
name: Run GoReleaser name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2 uses: goreleaser/goreleaser-action@v4
with: with:
version: latest version: latest
args: release --rm-dist args: release --rm-dist

36
domain/openapi/mgnt.go Normal file
View File

@@ -0,0 +1,36 @@
package openapi
import "github.com/silenceper/wechat/v2/util"
// GetAPIQuotaParams 查询API调用额度参数
type GetAPIQuotaParams struct {
CgiPath string `json:"cgi_path"` // api的请求地址例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会76003的报错
}
// APIQuota API调用额度
type APIQuota struct {
util.CommonError
Quota struct {
DailyLimit int64 `json:"daily_limit"` // 当天该账号可调用该接口的次数
Used int64 `json:"used"` // 当天已经调用的次数
Remain int64 `json:"remain"` // 当天剩余调用次数
} `json:"quota"` // 详情
}
// GetRidInfoParams 查询rid信息参数
type GetRidInfoParams struct {
Rid string `json:"rid"` // 调用接口报错返回的rid
}
// RidInfo rid信息
type RidInfo struct {
util.CommonError
Request struct {
InvokeTime int64 `json:"invoke_time"` // 发起请求的时间戳
CostInMs int64 `json:"cost_in_ms"` // 请求毫秒级耗时
RequestURL string `json:"request_url"` // 请求的URL参数
RequestBody string `json:"request_body"` // post请求的请求参数
ResponseBody string `json:"response_body"` // 接口请求返回参数
ClientIP string `json:"client_ip"` // 接口请求的客户端ip
} `json:"request"` // 该rid对应的请求详情
}

127
internal/openapi/mgnt.go Normal file
View File

@@ -0,0 +1,127 @@
package openapi
import (
"errors"
"fmt"
"github.com/silenceper/wechat/v2/domain/openapi"
mpContext "github.com/silenceper/wechat/v2/miniprogram/context"
ocContext "github.com/silenceper/wechat/v2/officialaccount/context"
"github.com/silenceper/wechat/v2/util"
)
const (
clearQuotaURL = "https://api.weixin.qq.com/cgi-bin/clear_quota" // 重置API调用次数
getAPIQuotaURL = "https://api.weixin.qq.com/cgi-bin/openapi/quota/get" // 查询API调用额度
getRidInfoURL = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get" // 查询rid信息
clearQuotaByAppSecretURL = "https://api.weixin.qq.com/cgi-bin/clear_quota/v2" // 使用AppSecret重置 API 调用次数
)
// OpenAPI openApi管理
type OpenAPI struct {
ctx interface{}
}
// NewOpenAPI 实例化
func NewOpenAPI(ctx interface{}) *OpenAPI {
return &OpenAPI{ctx: ctx}
}
// ClearQuota 重置API调用次数
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/clearQuota.html
func (o *OpenAPI) ClearQuota() error {
appID, _, err := o.getAppIDAndSecret()
if err != nil {
return err
}
var payload = struct {
AppID string `json:"appid"`
}{
AppID: appID,
}
res, err := o.doPostRequest(clearQuotaURL, payload)
if err != nil {
return err
}
return util.DecodeWithCommonError(res, "ClearQuota")
}
// GetAPIQuota 查询API调用额度
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/getApiQuota.html
func (o *OpenAPI) GetAPIQuota(params openapi.GetAPIQuotaParams) (quota openapi.APIQuota, err error) {
res, err := o.doPostRequest(getAPIQuotaURL, params)
if err != nil {
return
}
err = util.DecodeWithError(res, &quota, "GetAPIQuota")
return
}
// GetRidInfo 查询rid信息
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/getRidInfo.html
func (o *OpenAPI) GetRidInfo(params openapi.GetRidInfoParams) (r openapi.RidInfo, err error) {
res, err := o.doPostRequest(getRidInfoURL, params)
if err != nil {
return
}
err = util.DecodeWithError(res, &r, "GetRidInfo")
return
}
// ClearQuotaByAppSecret 使用AppSecret重置 API 调用次数
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/clearQuotaByAppSecret.html
func (o *OpenAPI) ClearQuotaByAppSecret() error {
id, secret, err := o.getAppIDAndSecret()
if err != nil {
return err
}
uri := fmt.Sprintf("%s?appid=%s&appsecret=%s", clearQuotaByAppSecretURL, id, secret)
res, err := util.HTTPPost(uri, "")
if err != nil {
return err
}
return util.DecodeWithCommonError(res, "ClearQuotaByAppSecret")
}
// 获取 AppID 和 AppSecret
func (o *OpenAPI) getAppIDAndSecret() (string, string, error) {
switch o.ctx.(type) {
case *mpContext.Context:
c := o.ctx.(*mpContext.Context)
return c.AppID, c.AppSecret, nil
case *ocContext.Context:
c := o.ctx.(*ocContext.Context)
return c.AppID, c.AppSecret, nil
default:
return "", "", errors.New("invalid context type")
}
}
// 获取 AccessToken
func (o *OpenAPI) getAccessToken() (string, error) {
switch o.ctx.(type) {
case *mpContext.Context:
return o.ctx.(*mpContext.Context).GetAccessToken()
case *ocContext.Context:
return o.ctx.(*ocContext.Context).GetAccessToken()
default:
return "", errors.New("invalid context type")
}
}
// 创建 POST 请求
func (o *OpenAPI) doPostRequest(uri string, payload interface{}) ([]byte, error) {
ak, err := o.getAccessToken()
if err != nil {
return nil, err
}
uri = fmt.Sprintf("%s?access_token=%s", uri, ak)
return util.PostJSON(uri, payload)
}

View File

@@ -40,8 +40,8 @@ type ResCode2Session struct {
type RspCheckEncryptedData struct { type RspCheckEncryptedData struct {
util.CommonError util.CommonError
Vaild bool `json:"vaild"` // 是否是合法的数据 Vaild bool `json:"vaild"` // 是否是合法的数据
CreateTime uint `json:"create_time"` // 加密数据生成的时间戳 CreateTime uint64 `json:"create_time"` // 加密数据生成的时间戳
} }
// Code2Session 登录凭证校验。 // Code2Session 登录凭证校验。

View File

@@ -2,6 +2,7 @@ package miniprogram
import ( import (
"github.com/silenceper/wechat/v2/credential" "github.com/silenceper/wechat/v2/credential"
"github.com/silenceper/wechat/v2/internal/openapi"
"github.com/silenceper/wechat/v2/miniprogram/analysis" "github.com/silenceper/wechat/v2/miniprogram/analysis"
"github.com/silenceper/wechat/v2/miniprogram/auth" "github.com/silenceper/wechat/v2/miniprogram/auth"
"github.com/silenceper/wechat/v2/miniprogram/business" "github.com/silenceper/wechat/v2/miniprogram/business"
@@ -126,3 +127,8 @@ func (miniProgram *MiniProgram) GetShortLink() *shortlink.ShortLink {
func (miniProgram *MiniProgram) GetSURLScheme() *urlscheme.URLScheme { func (miniProgram *MiniProgram) GetSURLScheme() *urlscheme.URLScheme {
return urlscheme.NewURLScheme(miniProgram.ctx) return urlscheme.NewURLScheme(miniProgram.ctx)
} }
// GetOpenAPI openApi管理接口
func (miniProgram *MiniProgram) GetOpenAPI() *openapi.OpenAPI {
return openapi.NewOpenAPI(miniProgram.ctx)
}

View File

@@ -123,6 +123,7 @@ type MixMessage struct {
Title string `xml:"Title"` Title string `xml:"Title"`
Description string `xml:"Description"` Description string `xml:"Description"`
URL string `xml:"Url"` URL string `xml:"Url"`
BizMsgMenuID int64 `xml:"bizmsgmenuid"`
// 事件相关 // 事件相关
Event EventType `xml:"Event" json:"Event"` Event EventType `xml:"Event" json:"Event"`
@@ -195,6 +196,14 @@ type MixMessage struct {
LegalPersonaName string `xml:"legal_persona_name"` LegalPersonaName string `xml:"legal_persona_name"`
ComponentPhone string `xml:"component_phone"` ComponentPhone string `xml:"component_phone"`
} `xml:"info"` } `xml:"info"`
ResultInfo struct {
APIName string `xml:"api_name"`
ApplyTime string `xml:"apply_time"`
AuditID string `xml:"audit_id"`
AuditTime string `xml:"audit_time"`
Reason string `xml:"reason"`
Status string `xml:"status"`
} `xml:"result_info"`
// 卡券相关 // 卡券相关
CardID string `xml:"CardId"` CardID string `xml:"CardId"`
@@ -213,6 +222,10 @@ type MixMessage struct {
TraceID string `xml:"trace_id"` TraceID string `xml:"trace_id"`
StatusCode int `xml:"status_code"` StatusCode int `xml:"status_code"`
//小程序名称审核结果事件推送
Ret int32 `xml:"ret"` //审核结果 2失败3成功
NickName string `xml:"nickname"` //小程序昵称
// 设备相关 // 设备相关
device.MsgDevice device.MsgDevice

View File

@@ -4,6 +4,7 @@ import (
stdcontext "context" stdcontext "context"
"net/http" "net/http"
"github.com/silenceper/wechat/v2/internal/openapi"
"github.com/silenceper/wechat/v2/officialaccount/draft" "github.com/silenceper/wechat/v2/officialaccount/draft"
"github.com/silenceper/wechat/v2/officialaccount/freepublish" "github.com/silenceper/wechat/v2/officialaccount/freepublish"
"github.com/silenceper/wechat/v2/officialaccount/ocr" "github.com/silenceper/wechat/v2/officialaccount/ocr"
@@ -212,3 +213,8 @@ func (officialAccount *OfficialAccount) GetSubscribe() *message.Subscribe {
func (officialAccount *OfficialAccount) GetCustomerServiceManager() *customerservice.Manager { func (officialAccount *OfficialAccount) GetCustomerServiceManager() *customerservice.Manager {
return customerservice.NewCustomerServiceManager(officialAccount.ctx) return customerservice.NewCustomerServiceManager(officialAccount.ctx)
} }
// GetOpenAPI openApi管理接口
func (officialAccount *OfficialAccount) GetOpenAPI() *openapi.OpenAPI {
return openapi.NewOpenAPI(officialAccount.ctx)
}

View File

@@ -9,6 +9,12 @@ import (
const ( const (
getAccountBasicInfoURL = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo" getAccountBasicInfoURL = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo"
checkNickNameURL = "https://api.weixin.qq.com/cgi-bin/wxverify/checkwxverifynickname"
setNickNameURL = "https://api.weixin.qq.com/wxa/setnickname"
setSignatureURL = "https://api.weixin.qq.com/cgi-bin/account/modifysignature"
setHeadImageURL = "https://api.weixin.qq.com/cgi-bin/account/modifyheadimage"
getSearchStatusURL = "https://api.weixin.qq.com/wxa/getwxasearchstatus"
setSearchStatusURL = "https://api.weixin.qq.com/wxa/changewxasearchstatus"
) )
// Basic 基础信息设置 // Basic 基础信息设置
@@ -51,3 +57,187 @@ func (basic *Basic) GetAccountBasicInfo() (*AccountBasicInfo, error) {
// TODO // TODO
// func (encryptor *Basic) modifyDomain() { // func (encryptor *Basic) modifyDomain() {
// } // }
// CheckNickNameResp 小程序名称检测结果
type CheckNickNameResp struct {
util.CommonError
HitCondition bool `json:"hit_condition"` // 是否命中关键字策略。若命中,可以选填关键字材料
Wording string `json:"wording"` // 命中关键字的说明描述
}
// CheckNickName 检测微信认证的名称是否符合规则
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/checkNickName.html
func (basic *Basic) CheckNickName(nickname string) (*CheckNickNameResp, error) {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return nil, err
}
url := fmt.Sprintf("%s?access_token=%s", checkNickNameURL, ak)
data, err := util.PostJSON(url, map[string]string{
"nick_name": nickname,
})
if err != nil {
return nil, err
}
result := &CheckNickNameResp{}
if err := util.DecodeWithError(data, result, "wxverify/checkwxverifynickname"); err != nil {
return nil, err
}
return result, nil
}
// SetNickNameResp 设置小程序名称结果
type SetNickNameResp struct {
util.CommonError
AuditID int64 `json:"audit_id"` // 审核单Id通过用于查询改名审核状态
Wording string `json:"wording"` // 材料说明
}
// SetNickNameParam 设置小程序名称参数
type SetNickNameParam struct {
NickName string `json:"nick_name"` // 昵称,不支持包含“小程序”关键字的昵称
IDCard string `json:"id_card,omitempty"` // 身份证照片 mediaid个人号必填
License string `json:"license,omitempty"` // 组织机构代码证或营业执照 mediaid组织号必填
NameingOtherStuff1 string `json:"naming_other_stuff_1,omitempty"` // 其他证明材料 mediaid选填
NameingOtherStuff2 string `json:"naming_other_stuff_2,omitempty"` // 其他证明材料 mediaid选填
NameingOtherStuff3 string `json:"naming_other_stuff_3,omitempty"` // 其他证明材料 mediaid选填
NameingOtherStuff4 string `json:"naming_other_stuff_4,omitempty"` // 其他证明材料 mediaid选填
NameingOtherStuff5 string `json:"naming_other_stuff_5,omitempty"` // 其他证明材料 mediaid选填
}
// SetNickName 设置小程序名称
func (basic *Basic) SetNickName(nickname string) (*SetNickNameResp, error) {
return basic.SetNickNameFull(&SetNickNameParam{
NickName: nickname,
})
}
// SetNickNameFull 设置小程序名称
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setNickName.html
func (basic *Basic) SetNickNameFull(param *SetNickNameParam) (*SetNickNameResp, error) {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return nil, err
}
url := fmt.Sprintf("%s?access_token=%s", setNickNameURL, ak)
data, err := util.PostJSON(url, param)
if err != nil {
return nil, err
}
result := &SetNickNameResp{}
if err := util.DecodeWithError(data, result, "setnickname"); err != nil {
return nil, err
}
return result, nil
}
// SetSignatureResp 小程序功能介绍修改结果
type SetSignatureResp struct {
util.CommonError
}
// SetSignature 小程序修改功能介绍
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setSignature.html
func (basic *Basic) SetSignature(signature string) error {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return err
}
url := fmt.Sprintf("%s?access_token=%s", setSignatureURL, ak)
data, err := util.PostJSON(url, map[string]string{
"signature": signature,
})
if err != nil {
return err
}
return util.DecodeWithError(data, &SetSignatureResp{}, "account/modifysignature")
}
// GetSearchStatusResp 查询小程序当前是否可被搜索
type GetSearchStatusResp struct {
util.CommonError
Status int `json:"status"` // 1 表示不可搜索0 表示可搜索
}
// GetSearchStatus 查询小程序当前是否可被搜索
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/getSearchStatus.html
func (basic *Basic) GetSearchStatus(signature string) (*GetSearchStatusResp, error) {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return nil, err
}
url := fmt.Sprintf("%s?access_token=%s", getSearchStatusURL, ak)
data, err := util.HTTPGet(url)
if err != nil {
return nil, err
}
result := &GetSearchStatusResp{}
if err := util.DecodeWithError(data, result, "getwxasearchstatus"); err != nil {
return nil, err
}
return result, nil
}
// SetSearchStatusResp 小程序是否可被搜索修改结果
type SetSearchStatusResp struct {
util.CommonError
}
// SetSearchStatus 修改小程序是否可被搜索
// status: 1 表示不可搜索0 表示可搜索
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setSearchStatus.html
func (basic *Basic) SetSearchStatus(status int) error {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return err
}
url := fmt.Sprintf("%s?access_token=%s", setSearchStatusURL, ak)
data, err := util.PostJSON(url, map[string]int{
"status": status,
})
if err != nil {
return err
}
return util.DecodeWithError(data, &SetSearchStatusResp{}, "changewxasearchstatus")
}
// SetHeadImageResp 小程序头像修改结果
type SetHeadImageResp struct {
util.CommonError
}
// SetHeadImageParam 小程序头像修改参数
type SetHeadImageParam struct {
HeadImageMediaID string `json:"head_img_media_id"` // 头像素材 media_id
X1 string `json:"x1"` // 裁剪框左上角 x 坐标(取值范围:[0, 1]
Y1 string `json:"y1"` // 裁剪框左上角 y 坐标(取值范围:[0, 1]
X2 string `json:"x2"` // 裁剪框右下角 x 坐标(取值范围:[0, 1]
Y2 string `json:"y2"` // 裁剪框右下角 y 坐标(取值范围:[0, 1]
}
// SetHeadImage 修改小程序头像
func (basic *Basic) SetHeadImage(imgMediaID string) error {
return basic.SetHeadImageFull(&SetHeadImageParam{
HeadImageMediaID: imgMediaID,
X1: "0",
Y1: "0",
X2: "1",
Y2: "1",
})
}
// SetHeadImageFull 修改小程序头像
// 新增临时素材: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setHeadImage.html
func (basic *Basic) SetHeadImageFull(param *SetHeadImageParam) error {
ak, err := basic.GetAuthrAccessToken(basic.AppID)
if err != nil {
return err
}
url := fmt.Sprintf("%s?access_token=%s", setHeadImageURL, ak)
data, err := util.PostJSON(url, param)
if err != nil {
return err
}
return util.DecodeWithError(data, &SetHeadImageResp{}, "account/modifyheadimage")
}

View File

@@ -9,6 +9,8 @@ import (
const ( const (
// departmentSimpleListURL 获取子部门ID列表 // departmentSimpleListURL 获取子部门ID列表
departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d" 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"
) )
type ( type (
@@ -23,6 +25,21 @@ type (
ParentID int `json:"parentid"` ParentID int `json:"parentid"`
Order int `json:"order"` 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值大的排序靠前
}
) )
// DepartmentSimpleList 获取子部门ID列表 // DepartmentSimpleList 获取子部门ID列表
@@ -45,3 +62,25 @@ func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error)
} }
return result.DepartmentID, nil return result.DepartmentID, nil
} }
// DepartmentList 获取部门列表
// @desc https://developer.work.weixin.qq.com/document/path/90208
func (r *Client) DepartmentList() ([]*Department, error) {
// 获取accessToken
accessToken, err := r.GetAccessToken()
if err != nil {
return nil, err
}
// 发起http请求
response, err := util.HTTPGet(fmt.Sprintf(departmentListURL, accessToken))
if err != nil {
return nil, err
}
// 按照结构体解析返回值
result := &DepartmentListResponse{}
if err = util.DecodeWithError(response, result, "DepartmentList"); err != nil {
return nil, err
}
// 返回数据
return result.Department, err
}

View File

@@ -0,0 +1,230 @@
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{}
if err = util.DecodeWithError(response, result, "GetPermList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetLinkedCorpUser"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "LinkedCorpSimpleList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "LinkedCorpUserList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "LinkedCorpDepartmentList"); err != nil {
return nil, err
}
return result, nil
}

View File

@@ -16,6 +16,18 @@ const (
fetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user" fetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
// updateUserRemarkURL 更新客户备注信息 // updateUserRemarkURL 更新客户备注信息
updateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark" 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 外部联系人列表响应 // ExternalUserListResponse 外部联系人列表响应
@@ -71,7 +83,7 @@ type FollowUser struct {
UserID string `json:"userid"` UserID string `json:"userid"`
Remark string `json:"remark"` Remark string `json:"remark"`
Description string `json:"description"` Description string `json:"description"`
CreateTime string `json:"create_time"` CreateTime int64 `json:"createtime"`
Tags []Tag `json:"tags"` Tags []Tag `json:"tags"`
RemarkCorpName string `json:"remark_corp_name"` RemarkCorpName string `json:"remark_corp_name"`
RemarkMobiles []string `json:"remark_mobiles"` RemarkMobiles []string `json:"remark_mobiles"`
@@ -157,7 +169,7 @@ type FollowInfo struct {
UserID string `json:"userid"` UserID string `json:"userid"`
Remark string `json:"remark"` Remark string `json:"remark"`
Description string `json:"description"` Description string `json:"description"`
CreateTime int `json:"create_time"` CreateTime int64 `json:"createtime"`
TagID []string `json:"tag_id"` TagID []string `json:"tag_id"`
RemarkCorpName string `json:"remark_corp_name"` RemarkCorpName string `json:"remark_corp_name"`
RemarkMobiles []string `json:"remark_mobiles"` RemarkMobiles []string `json:"remark_mobiles"`
@@ -219,3 +231,236 @@ func (r *Client) UpdateUserRemark(request UpdateUserRemarkRequest) error {
} }
return util.DecodeWithCommonError(response, "UpdateUserRemark") 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{}
if err = util.DecodeWithError(response, result, "ListCustomerStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetCustomerStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetRangeCustomerStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "CreateCustomerStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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")
}

View File

@@ -80,7 +80,7 @@ type (
ChatID string `json:"chat_id"` //客户群ID ChatID string `json:"chat_id"` //客户群ID
Name string `json:"name"` //群名 Name string `json:"name"` //群名
Owner string `json:"owner"` //群主ID Owner string `json:"owner"` //群主ID
CreateTime int `json:"create_time"` //群的创建时间 CreateTime int64 `json:"create_time"` //群的创建时间
Notice string `json:"notice"` //群公告 Notice string `json:"notice"` //群公告
MemberList []GroupChatMember `json:"member_list"` //群成员列表 MemberList []GroupChatMember `json:"member_list"` //群成员列表
AdminList []GroupChatAdmin `json:"admin_list"` //群管理员列表 AdminList []GroupChatAdmin `json:"admin_list"` //群管理员列表

View File

@@ -0,0 +1,658 @@
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{}
if err = util.DecodeWithError(response, result, "AddMomentTask"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentTaskResult"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentTask"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentCustomerList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentSendResult"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentComments"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "ListMomentStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetMomentStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetRangeMomentStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "CreateMomentStrategy"); err != nil {
return nil, err
}
return result, nil
}
// 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")
}

View File

@@ -111,8 +111,8 @@ func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResp
// GetGroupMsgListV2Request 获取群发记录列表请求 // GetGroupMsgListV2Request 获取群发记录列表请求
type GetGroupMsgListV2Request struct { type GetGroupMsgListV2Request struct {
ChatType string `json:"chat_type"` ChatType string `json:"chat_type"`
StartTime int `json:"start_time"` StartTime int64 `json:"start_time"`
EndTime int `json:"end_time"` EndTime int64 `json:"end_time"`
Creator string `json:"creator,omitempty"` Creator string `json:"creator,omitempty"`
FilterType int `json:"filter_type"` FilterType int `json:"filter_type"`
Limit int `json:"limit"` Limit int `json:"limit"`
@@ -130,7 +130,7 @@ type GetGroupMsgListV2Response struct {
type GroupMsg struct { type GroupMsg struct {
MsgID string `json:"msgid"` MsgID string `json:"msgid"`
Creator string `json:"creator"` Creator string `json:"creator"`
CreateTime int `json:"create_time"` CreateTime int64 `json:"create_time"`
CreateType int `json:"create_type"` CreateType int `json:"create_type"`
Text MsgText `json:"text"` Text MsgText `json:"text"`
Attachments []*Attachment `json:"attachments"` Attachments []*Attachment `json:"attachments"`

View File

@@ -18,6 +18,14 @@ const (
delCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag" delCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
// markCropTagURL 为客户打上、删除标签 // markCropTagURL 为客户打上、删除标签
markCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag" 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 获取企业标签请求 // GetCropTagRequest 获取企业标签请求
@@ -36,7 +44,7 @@ type GetCropTagListResponse struct {
type TagGroup struct { type TagGroup struct {
GroupID string `json:"group_id"` GroupID string `json:"group_id"`
GroupName string `json:"group_name"` GroupName string `json:"group_name"`
CreateTime int `json:"create_time"` CreateTime int64 `json:"create_time"`
GroupOrder int `json:"group_order"` GroupOrder int `json:"group_order"`
Deleted bool `json:"deleted"` Deleted bool `json:"deleted"`
Tag []TagGroupTagItem `json:"tag"` Tag []TagGroupTagItem `json:"tag"`
@@ -46,7 +54,7 @@ type TagGroup struct {
type TagGroupTagItem struct { type TagGroupTagItem struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
CreateTime int `json:"create_time"` CreateTime int64 `json:"create_time"`
Order int `json:"order"` Order int `json:"order"`
Deleted bool `json:"deleted"` Deleted bool `json:"deleted"`
} }
@@ -201,3 +209,161 @@ func (r *Client) MarkTag(request MarkTagRequest) error {
} }
return util.DecodeWithCommonError(response, "MarkTag") 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{}
if err = util.DecodeWithError(response, result, "GetStrategyTagList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "AddStrategyTag"); err != nil {
return nil, err
}
return result, nil
}
// 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")
}

View File

@@ -0,0 +1,291 @@
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{}
if err = util.DecodeWithError(response, result, "TransferCustomer"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "TransferResult"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GroupChatOnJobTransfer"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetUnassignedList"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "ResignedTransferCustomer"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "ResignedTransferResult"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GroupChatTransfer"); err != nil {
return nil, err
}
return result, nil
}

17
work/invoice/client.go Normal file
View 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,
}
}

191
work/invoice/invoice.go Normal file
View File

@@ -0,0 +1,191 @@
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{}
if err = util.DecodeWithError(response, result, "GetInvoiceInfo"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetInvoiceInfoBatch"); err != nil {
return nil, err
}
return result, nil
}

View File

@@ -53,7 +53,7 @@ type callbackOriginMessage struct {
// CallbackMessage 微信客服回调消息 // CallbackMessage 微信客服回调消息
type CallbackMessage struct { type CallbackMessage struct {
ToUserName string `json:"to_user_name" xml:"ToUserName"` // 微信客服组件ID ToUserName string `json:"to_user_name" xml:"ToUserName"` // 微信客服组件ID
CreateTime int `json:"create_time" xml:"CreateTime"` // 消息创建时间unix时间戳 CreateTime int64 `json:"create_time" xml:"CreateTime"` // 消息创建时间unix时间戳
MsgType string `json:"msgtype" xml:"MsgType"` // 消息的类型,此时固定为 event MsgType string `json:"msgtype" xml:"MsgType"` // 消息的类型,此时固定为 event
Event string `json:"event" xml:"Event"` // 事件的类型,此时固定为 kf_msg_or_event Event string `json:"event" xml:"Event"` // 事件的类型,此时固定为 kf_msg_or_event
Token string `json:"token" xml:"Token"` // 调用拉取消息接口时需要传此token用于校验请求的合法性 Token string `json:"token" xml:"Token"` // 调用拉取消息接口时需要传此token用于校验请求的合法性

View File

@@ -169,7 +169,7 @@ type CollectMessage struct {
Collect struct { Collect struct {
RoomName string `json:"room_name,omitempty"` // 填表消息所在的群名称。 RoomName string `json:"room_name,omitempty"` // 填表消息所在的群名称。
Creator string `json:"creator,omitempty"` // 创建者在群中的名字 Creator string `json:"creator,omitempty"` // 创建者在群中的名字
CreateTime string `json:"create_time,omitempty"` // 创建的时间 CreateTime int64 `json:"create_time,omitempty"` // 创建的时间
Details []CollectDetails `json:"details,omitempty"` // 表内容 Details []CollectDetails `json:"details,omitempty"` // 表内容
} `json:"collect,omitempty"` } `json:"collect,omitempty"`
} }

View File

@@ -23,6 +23,10 @@ var (
oauthUserInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s" oauthUserInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s"
// oauthQrContentTargetURL 构造独立窗口登录二维码 // oauthQrContentTargetURL 构造独立窗口登录二维码
oauthQrContentTargetURL = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&redirect_uri=%s&state=%s" oauthQrContentTargetURL = "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&redirect_uri=%s&state=%s"
// 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 // NewOauth new init oauth
@@ -93,3 +97,73 @@ func (ctr *Oauth) UserFromCode(code string) (result ResUserInfo, err error) {
} }
return 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
if response, err = util.HTTPGet(fmt.Sprintf(getUserInfoURL, accessToken, code)); err != nil {
return nil, err
}
result := &GetUserInfoResponse{}
if err = util.DecodeWithError(response, result, "GetUserInfo"); err != nil {
return nil, err
}
return result, nil
}
// 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{}
if err = util.DecodeWithError(response, result, "GetUserDetail"); err != nil {
return nil, err
}
return result, nil
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/silenceper/wechat/v2/work/config" "github.com/silenceper/wechat/v2/work/config"
"github.com/silenceper/wechat/v2/work/context" "github.com/silenceper/wechat/v2/work/context"
"github.com/silenceper/wechat/v2/work/externalcontact" "github.com/silenceper/wechat/v2/work/externalcontact"
"github.com/silenceper/wechat/v2/work/invoice"
"github.com/silenceper/wechat/v2/work/kf" "github.com/silenceper/wechat/v2/work/kf"
"github.com/silenceper/wechat/v2/work/material" "github.com/silenceper/wechat/v2/work/material"
"github.com/silenceper/wechat/v2/work/message" "github.com/silenceper/wechat/v2/work/message"
@@ -79,3 +80,8 @@ func (wk *Work) GetMessage() *message.Client {
func (wk *Work) GetAppChat() *appchat.Client { func (wk *Work) GetAppChat() *appchat.Client {
return appchat.NewClient(wk.ctx) return appchat.NewClient(wk.ctx)
} }
// GetInvoice get invoice
func (wk *Work) GetInvoice() *invoice.Client {
return invoice.NewClient(wk.ctx)
}