mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-21 12:52:26 +08:00
Compare commits
7 Commits
v2.1.8
...
cf42cd8d54
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf42cd8d54 | ||
|
|
85ee45580b | ||
|
|
208d5c528a | ||
|
|
b5f9a8933e | ||
|
|
52fb5596d3 | ||
|
|
44150c557e | ||
|
|
635a0c640d |
@@ -81,7 +81,7 @@ func (auth *Auth) CheckEncryptedDataContext(ctx context2.Context, encryptedMsgHa
|
|||||||
var (
|
var (
|
||||||
at string
|
at string
|
||||||
)
|
)
|
||||||
if at, err = auth.GetAccessToken(); err != nil {
|
if at, err = auth.GetAccessTokenContext(ctx); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ func (auth *Auth) GetPhoneNumberContext(ctx context2.Context, code string) (*Get
|
|||||||
at string
|
at string
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if at, err = auth.GetAccessToken(); err != nil {
|
if at, err = auth.GetAccessTokenContext(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
body := map[string]interface{}{
|
body := map[string]interface{}{
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const (
|
|||||||
getComponentInfoURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%s"
|
getComponentInfoURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%s"
|
||||||
componentLoginURL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=%d&biz_appid=%s"
|
componentLoginURL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=%d&biz_appid=%s"
|
||||||
bindComponentURL = "https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&auth_type=%d&no_scan=1&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&biz_appid=%s#wechat_redirect"
|
bindComponentURL = "https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&auth_type=%d&no_scan=1&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&biz_appid=%s#wechat_redirect"
|
||||||
|
bindComponentURLV2 = "https://open.weixin.qq.com/wxaopen/safe/bindcomponent?action=bindcomponent&auth_type=%d&no_scan=1&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&biz_appid=%s#wechat_redirect"
|
||||||
// TODO 获取授权方选项信息
|
// TODO 获取授权方选项信息
|
||||||
// getComponentConfigURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token=%s"
|
// getComponentConfigURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token=%s"
|
||||||
// TODO 获取已授权的账号信息
|
// TODO 获取已授权的账号信息
|
||||||
@@ -137,6 +138,20 @@ func (ctx *Context) GetBindComponentURL(redirectURI string, authType int, bizApp
|
|||||||
return ctx.GetBindComponentURLContext(context.Background(), redirectURI, authType, bizAppID)
|
return ctx.GetBindComponentURLContext(context.Background(), redirectURI, authType, bizAppID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBindComponentURLV2Context 获取新版本第三方公众号授权链接(链接跳转,适用移动端)
|
||||||
|
func (ctx *Context) GetBindComponentURLV2Context(stdCtx context.Context, redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
|
code, err := ctx.GetPreCodeContext(stdCtx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(bindComponentURLV2, authType, ctx.AppID, code, url.QueryEscape(redirectURI), bizAppID), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBindComponentURLV2 获取新版本第三方公众号授权链接(链接跳转,适用移动端)
|
||||||
|
func (ctx *Context) GetBindComponentURLV2(redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
|
return ctx.GetBindComponentURLContext(context.Background(), redirectURI, authType, bizAppID)
|
||||||
|
}
|
||||||
|
|
||||||
// ID 微信返回接口中各种类型字段
|
// ID 微信返回接口中各种类型字段
|
||||||
type ID struct {
|
type ID struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
@@ -225,6 +240,10 @@ func (ctx *Context) RefreshAuthrTokenContext(stdCtx context.Context, appid, refr
|
|||||||
if err := cache.SetContext(stdCtx, ctx.Cache, authrTokenKey, ret.AccessToken, time.Second*time.Duration(ret.ExpiresIn-30)); err != nil {
|
if err := cache.SetContext(stdCtx, ctx.Cache, authrTokenKey, ret.AccessToken, time.Second*time.Duration(ret.ExpiresIn-30)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
refreshTokenKey := "authorizer_refresh_token_" + appid
|
||||||
|
if err := cache.SetContext(stdCtx, ctx.Cache, refreshTokenKey, ret.RefreshToken, 10*365*24*60*60*time.Second); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,8 +257,18 @@ func (ctx *Context) GetAuthrAccessTokenContext(stdCtx context.Context, appid str
|
|||||||
authrTokenKey := "authorizer_access_token_" + appid
|
authrTokenKey := "authorizer_access_token_" + appid
|
||||||
val := cache.GetContext(stdCtx, ctx.Cache, authrTokenKey)
|
val := cache.GetContext(stdCtx, ctx.Cache, authrTokenKey)
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return "", fmt.Errorf("cannot get authorizer %s access token", appid)
|
refreshTokenKey := "authorizer_refresh_token_" + appid
|
||||||
|
val := cache.GetContext(stdCtx, ctx.Cache, refreshTokenKey)
|
||||||
|
if val == nil {
|
||||||
|
return "", fmt.Errorf("cannot get authorizer %s refresh token", appid)
|
||||||
|
}
|
||||||
|
token, err := ctx.RefreshAuthrTokenContext(stdCtx, appid, val.(string))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return token.AccessToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return val.(string), nil
|
return val.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ type UserUpdateRequest struct {
|
|||||||
Gender int `json:"gender"`
|
Gender int `json:"gender"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
BizMail string `json:"biz_mail"`
|
BizMail string `json:"biz_mail"`
|
||||||
|
BizMailAlias string `json:"biz_mail_alias"`
|
||||||
IsLeaderInDept []int `json:"is_leader_in_dept"`
|
IsLeaderInDept []int `json:"is_leader_in_dept"`
|
||||||
DirectLeader []string `json:"direct_leader"`
|
DirectLeader []string `json:"direct_leader"`
|
||||||
Enable int `json:"enable"`
|
Enable int `json:"enable"`
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const (
|
|||||||
clearOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/clear_checkin_option_array_field?access_token=%s"
|
clearOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/clear_checkin_option_array_field?access_token=%s"
|
||||||
// delOptionURL 删除打卡规则
|
// delOptionURL 删除打卡规则
|
||||||
delOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/del_checkin_option?access_token=%s"
|
delOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/del_checkin_option?access_token=%s"
|
||||||
|
// addRecordURL 添加打卡记录
|
||||||
|
addRecordURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/add_checkin_record?access_token=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetScheduleListRequest 为打卡人员排班请求
|
// SetScheduleListRequest 为打卡人员排班请求
|
||||||
@@ -140,6 +142,7 @@ type OptionGroupRule struct {
|
|||||||
SyncOutCheckin bool `json:"sync_out_checkin,omitempty"`
|
SyncOutCheckin bool `json:"sync_out_checkin,omitempty"`
|
||||||
BukaRemind OptionGroupBukaRemind `json:"buka_remind,omitempty"`
|
BukaRemind OptionGroupBukaRemind `json:"buka_remind,omitempty"`
|
||||||
BukaRestriction int64 `json:"buka_restriction,omitempty"`
|
BukaRestriction int64 `json:"buka_restriction,omitempty"`
|
||||||
|
CheckinMethodType int64 `json:"checkin_method_type,omitempty"`
|
||||||
SpanDayTime int64 `json:"span_day_time,omitempty"`
|
SpanDayTime int64 `json:"span_day_time,omitempty"`
|
||||||
StandardWorkDuration int64 `json:"standard_work_duration,omitempty"`
|
StandardWorkDuration int64 `json:"standard_work_duration,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -385,3 +388,41 @@ func (r *Client) DelOption(req *DelOptionRequest) error {
|
|||||||
}
|
}
|
||||||
return util.DecodeWithCommonError(response, "DelOption")
|
return util.DecodeWithCommonError(response, "DelOption")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddRecordRequest 添加打卡记录请求
|
||||||
|
type AddRecordRequest struct {
|
||||||
|
Records []Record `json:"records"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record 打卡记录
|
||||||
|
type Record struct {
|
||||||
|
UserID string `json:"userid"`
|
||||||
|
CheckinTime int64 `json:"checkin_time"`
|
||||||
|
LocationTitle string `json:"location_title"`
|
||||||
|
LocationDetail string `json:"location_detail"`
|
||||||
|
MediaIDS []string `json:"mediaids"`
|
||||||
|
Notes string `json:"notes"`
|
||||||
|
DeviceType int `json:"device_type"`
|
||||||
|
Lat int64 `json:"lat"`
|
||||||
|
Lng int64 `json:"lng"`
|
||||||
|
DeviceDetail string `json:"device_detail"`
|
||||||
|
WifiName string `json:"wifiname"`
|
||||||
|
WifiMac string `json:"wifimac"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRecord 添加打卡记录
|
||||||
|
// see https://developer.work.weixin.qq.com/document/path/99647
|
||||||
|
func (r *Client) AddRecord(req *AddRecordRequest) 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(addRecordURL, accessToken), req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return util.DecodeWithCommonError(response, "AddRecord")
|
||||||
|
}
|
||||||
|
|||||||
@@ -173,9 +173,15 @@ type (
|
|||||||
|
|
||||||
// OtInfo 加班信息
|
// OtInfo 加班信息
|
||||||
OtInfo struct {
|
OtInfo struct {
|
||||||
OtStatus int64 `json:"ot_status"`
|
OtStatus int64 `json:"ot_status"`
|
||||||
OtDuration int64 `json:"ot_duration"`
|
OtDuration int64 `json:"ot_duration"`
|
||||||
ExceptionDuration []uint64 `json:"exception_duration"`
|
ExceptionDuration []uint64 `json:"exception_duration"`
|
||||||
|
WorkdayOverAsVacation int64 `json:"workday_over_as_vacation"`
|
||||||
|
WorkdayOverAsMoney int64 `json:"workday_over_as_money"`
|
||||||
|
RestdayOverAsVacation int64 `json:"restday_over_as_vacation"`
|
||||||
|
RestdayOverAsMoney int64 `json:"restday_over_as_money"`
|
||||||
|
HolidayOverAsVacation int64 `json:"holiday_over_as_vacation"`
|
||||||
|
HolidayOverAsMoney int64 `json:"holiday_over_as_money"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -237,13 +243,20 @@ type (
|
|||||||
RegularDays int64 `json:"regular_days"`
|
RegularDays int64 `json:"regular_days"`
|
||||||
RegularWorkSec int64 `json:"regular_work_sec"`
|
RegularWorkSec int64 `json:"regular_work_sec"`
|
||||||
StandardWorkSec int64 `json:"standard_work_sec"`
|
StandardWorkSec int64 `json:"standard_work_sec"`
|
||||||
|
RestDays int64 `json:"rest_days"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverWorkInfo 加班情况
|
// OverWorkInfo 加班情况
|
||||||
OverWorkInfo struct {
|
OverWorkInfo struct {
|
||||||
WorkdayOverSec int64 `json:"workday_over_sec"`
|
WorkdayOverSec int64 `json:"workday_over_sec"`
|
||||||
HolidayOverSec int64 `json:"holidays_over_sec"`
|
HolidayOverSec int64 `json:"holidays_over_sec"`
|
||||||
RestDayOverSec int64 `json:"restdays_over_sec"`
|
RestDayOverSec int64 `json:"restdays_over_sec"`
|
||||||
|
WorkdaysOverAsVacation int64 `json:"workdays_over_as_vacation"`
|
||||||
|
WorkdaysOverAsMoney int64 `json:"workdays_over_as_money"`
|
||||||
|
RestdaysOverAsVacation int64 `json:"restdays_over_as_vacation"`
|
||||||
|
RestdaysOverAsMoney int64 `json:"restdays_over_as_money"`
|
||||||
|
HolidaysOverAsVacation int64 `json:"holidays_over_as_vacation"`
|
||||||
|
HolidaysOverAsMoney int64 `json:"holidays_over_as_money"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -304,6 +317,10 @@ type CorpOptionGroup struct {
|
|||||||
BukaRestriction int64 `json:"buka_restriction"`
|
BukaRestriction int64 `json:"buka_restriction"`
|
||||||
ScheduleList []ScheduleList `json:"schedulelist"`
|
ScheduleList []ScheduleList `json:"schedulelist"`
|
||||||
OffWorkIntervalTime int64 `json:"offwork_interval_time"`
|
OffWorkIntervalTime int64 `json:"offwork_interval_time"`
|
||||||
|
SpanDayTime int64 `json:"span_day_time"`
|
||||||
|
StandardWorkDuration int64 `json:"standard_work_duration"`
|
||||||
|
OpenSpCheckin bool `json:"open_sp_checkin"`
|
||||||
|
CheckinMethodType int64 `json:"checkin_method_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupCheckinDate 打卡时间,当规则类型为排班时没有意义
|
// GroupCheckinDate 打卡时间,当规则类型为排班时没有意义
|
||||||
@@ -505,6 +522,7 @@ type OptionInfo struct {
|
|||||||
type OptionGroup struct {
|
type OptionGroup struct {
|
||||||
GroupType int64 `json:"grouptype"`
|
GroupType int64 `json:"grouptype"`
|
||||||
GroupID int64 `json:"groupid"`
|
GroupID int64 `json:"groupid"`
|
||||||
|
OpenSpCheckin bool `json:"open_sp_checkin"`
|
||||||
GroupName string `json:"groupname"`
|
GroupName string `json:"groupname"`
|
||||||
CheckinDate []OptionCheckinDate `json:"checkindate"`
|
CheckinDate []OptionCheckinDate `json:"checkindate"`
|
||||||
SpeWorkdays []SpeWorkdays `json:"spe_workdays"`
|
SpeWorkdays []SpeWorkdays `json:"spe_workdays"`
|
||||||
@@ -518,6 +536,10 @@ type OptionGroup struct {
|
|||||||
LocInfos []LocInfos `json:"loc_infos"`
|
LocInfos []LocInfos `json:"loc_infos"`
|
||||||
ScheduleList []ScheduleList `json:"schedulelist"`
|
ScheduleList []ScheduleList `json:"schedulelist"`
|
||||||
BukaRestriction int64 `json:"buka_restriction"`
|
BukaRestriction int64 `json:"buka_restriction"`
|
||||||
|
SpanDayTime int64 `json:"span_day_time"`
|
||||||
|
StandardWorkDuration int64 `json:"standard_work_duration"`
|
||||||
|
OffWorkIntervalTime int64 `json:"offwork_interval_time"`
|
||||||
|
CheckinMethodType int64 `json:"checkin_method_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionCheckinDate 打卡时间配置
|
// OptionCheckinDate 打卡时间配置
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ const (
|
|||||||
customerAcquisitionQuotaURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition_quota?access_token=%s"
|
customerAcquisitionQuotaURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition_quota?access_token=%s"
|
||||||
// customerAcquisitionStatistic 查询链接使用详情
|
// customerAcquisitionStatistic 查询链接使用详情
|
||||||
customerAcquisitionStatisticURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/statistic?access_token=%s"
|
customerAcquisitionStatisticURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/statistic?access_token=%s"
|
||||||
|
// customerAcquisitionGetChatInfo 获取成员多次收消息详情
|
||||||
|
customerAcquisitionGetChatInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/get_chat_info?access_token=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -308,3 +310,42 @@ func (r *Client) CustomerAcquisitionStatistic(req *CustomerAcquisitionStatisticR
|
|||||||
err = util.DecodeWithError(response, result, "CustomerAcquisitionStatistic")
|
err = util.DecodeWithError(response, result, "CustomerAcquisitionStatistic")
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GetChatInfoRequest 获取成员多次收消息详情请求
|
||||||
|
GetChatInfoRequest struct {
|
||||||
|
ChatKey string `json:"chat_key"`
|
||||||
|
}
|
||||||
|
// GetChatInfoResponse 获取成员多次收消息详情响应
|
||||||
|
GetChatInfoResponse struct {
|
||||||
|
util.CommonError
|
||||||
|
UserID string `json:"userid"`
|
||||||
|
ExternalUserID string `json:"external_userid"`
|
||||||
|
ChatInfo ChatInfo `json:"chat_info"`
|
||||||
|
}
|
||||||
|
// ChatInfo 聊天信息
|
||||||
|
ChatInfo struct {
|
||||||
|
RecvMsgCnt int64 `json:"recv_msg_cnt"` // 成员收到的此客户的消息次数
|
||||||
|
LinkID string `json:"link_id"` // 成员添加客户的获客链接id
|
||||||
|
State string `json:"state"` // 成员添加客户的state
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetChatInfo 获取成员多次收消息详情
|
||||||
|
// see https://developer.work.weixin.qq.com/document/path/100130
|
||||||
|
func (r *Client) GetChatInfo(req *GetChatInfoRequest) (*GetChatInfoResponse, 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(customerAcquisitionGetChatInfoURL, accessToken), req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := &GetChatInfoResponse{}
|
||||||
|
err = util.DecodeWithError(response, result, "GetChatInfo")
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user