mirror of
https://github.com/silenceper/wechat.git
synced 2026-11-16 05:12:03 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8409760713 | ||
|
|
ad48392a5b |
No files matched your search
@@ -48,3 +48,12 @@ TODO
|
||||
| :----------------: | -------- | :------------------- | ---------- | ------------------------------------------ |
|
||||
| 获取用户的安全等级 | POST | /wxa/getuserriskrank | YES | (riskControl *RiskControl) GetUserRiskRank |
|
||||
|
||||
|
||||
## 学生身份
|
||||
|
||||
[官方文档](https://developers.weixin.qq.com/miniprogram/dev/server/API/student/api_quickcheckstudentidentity.html)
|
||||
|
||||
| 名称 | 请求方式 | URL | 是否已实现 | 使用方法 |
|
||||
| :--------------: | -------- | :------------------------------ | ---------- | ----------------------------------------------- |
|
||||
| 快速获取学生身份 | POST | /intp/quickcheckstudentidentity | YES | (student *Student) QuickCheckStudentIdentity |
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
context2 "context"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/silenceper/wechat/v2/miniprogram/context"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// defaultBaseURL 微信 API 默认基础地址
|
||||
const defaultBaseURL = "https://api.weixin.qq.com"
|
||||
|
||||
// Generic 通用 API 调用,用于访问 SDK 尚未封装的小程序接口。
|
||||
// 支持自定义 path、query 参数、request body 以及 response 结构体。
|
||||
type Generic struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewGeneric init
|
||||
func NewGeneric(ctx *context.Context) *Generic {
|
||||
return &Generic{ctx}
|
||||
}
|
||||
|
||||
// BuildURL 构建完整请求 URL。
|
||||
// path 支持相对路径(如 "/intp/xxx")或完整 URL(如 "https://api.weixin.qq.com/intp/xxx")。
|
||||
// query 为额外的 URL 查询参数,可为 nil;access_token 会自动追加(若 query 中已包含则不重复追加)。
|
||||
func (g *Generic) BuildURL(path string, query url.Values) (string, error) {
|
||||
return g.BuildURLContext(context2.Background(), path, query)
|
||||
}
|
||||
|
||||
// BuildURLContext 构建完整请求 URL(带 context)
|
||||
func (g *Generic) BuildURLContext(ctx context2.Context, path string, query url.Values) (string, error) {
|
||||
var baseURL string
|
||||
switch {
|
||||
case strings.HasPrefix(path, "http://"), strings.HasPrefix(path, "https://"):
|
||||
baseURL = path
|
||||
case strings.HasPrefix(path, "/"):
|
||||
baseURL = defaultBaseURL + path
|
||||
default:
|
||||
baseURL = defaultBaseURL + "/" + path
|
||||
}
|
||||
|
||||
// 克隆 query,避免修改调用方原始值
|
||||
q := make(url.Values, len(query)+1)
|
||||
for k, v := range query {
|
||||
q[k] = v
|
||||
}
|
||||
|
||||
// 自动追加 access_token
|
||||
if q.Get("access_token") == "" {
|
||||
accessToken, err := g.GetAccessTokenContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
q.Set("access_token", accessToken)
|
||||
}
|
||||
|
||||
sep := "?"
|
||||
if strings.Contains(baseURL, "?") {
|
||||
sep = "&"
|
||||
}
|
||||
return baseURL + sep + q.Encode(), nil
|
||||
}
|
||||
|
||||
// Get 发送 GET 请求,返回原始响应字节。
|
||||
// 使用 util.DecodeWithError 可将响应解码到自定义结构体。
|
||||
func (g *Generic) Get(path string, query url.Values) (response []byte, err error) {
|
||||
return g.GetContext(context2.Background(), path, query)
|
||||
}
|
||||
|
||||
// GetContext 发送 GET 请求(带 context),返回原始响应字节
|
||||
func (g *Generic) GetContext(ctx context2.Context, path string, query url.Values) (response []byte, err error) {
|
||||
var uri string
|
||||
if uri, err = g.BuildURLContext(ctx, path, query); err != nil {
|
||||
return
|
||||
}
|
||||
return util.HTTPGetContext(ctx, uri)
|
||||
}
|
||||
|
||||
// PostJSON 发送 POST 请求(JSON body),返回原始响应字节。
|
||||
// body 可为 nil(无请求体);使用 util.DecodeWithError 可将响应解码到自定义结构体。
|
||||
func (g *Generic) PostJSON(path string, query url.Values, body interface{}) (response []byte, err error) {
|
||||
return g.PostJSONContext(context2.Background(), path, query, body)
|
||||
}
|
||||
|
||||
// PostJSONContext 发送 POST 请求(JSON body,带 context),返回原始响应字节
|
||||
func (g *Generic) PostJSONContext(ctx context2.Context, path string, query url.Values, body interface{}) (response []byte, err error) {
|
||||
var uri string
|
||||
if uri, err = g.BuildURLContext(ctx, path, query); err != nil {
|
||||
return
|
||||
}
|
||||
return util.PostJSONContext(ctx, uri, body)
|
||||
}
|
||||
|
||||
// GetDecode 发送 GET 请求并将响应解码到 resp。
|
||||
// resp 应为指向结构体的指针,结构体中可嵌入 util.CommonError 以自动校验错误码。
|
||||
// apiName 用于错误信息标识。
|
||||
func (g *Generic) GetDecode(path string, query url.Values, resp interface{}, apiName string) (err error) {
|
||||
return g.GetDecodeContext(context2.Background(), path, query, resp, apiName)
|
||||
}
|
||||
|
||||
// GetDecodeContext 发送 GET 请求并将响应解码到 resp(带 context)
|
||||
func (g *Generic) GetDecodeContext(ctx context2.Context, path string, query url.Values, resp interface{}, apiName string) (err error) {
|
||||
var response []byte
|
||||
if response, err = g.GetContext(ctx, path, query); err != nil {
|
||||
return
|
||||
}
|
||||
return util.DecodeWithError(response, resp, apiName)
|
||||
}
|
||||
|
||||
// PostJSONDecode 发送 POST 请求(JSON body)并将响应解码到 resp。
|
||||
// resp 应为指向结构体的指针,结构体中可嵌入 util.CommonError 以自动校验错误码。
|
||||
// apiName 用于错误信息标识。
|
||||
func (g *Generic) PostJSONDecode(path string, query url.Values, body, resp interface{}, apiName string) (err error) {
|
||||
return g.PostJSONDecodeContext(context2.Background(), path, query, body, resp, apiName)
|
||||
}
|
||||
|
||||
// PostJSONDecodeContext 发送 POST 请求(JSON body)并将响应解码到 resp(带 context)
|
||||
func (g *Generic) PostJSONDecodeContext(ctx context2.Context, path string, query url.Values, body, resp interface{}, apiName string) (err error) {
|
||||
var response []byte
|
||||
if response, err = g.PostJSONContext(ctx, path, query, body); err != nil {
|
||||
return
|
||||
}
|
||||
return util.DecodeWithError(response, resp, apiName)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/silenceper/wechat/v2/miniprogram/context"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/encryptor"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/express"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/generic"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/message"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/minidrama"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/ocr"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
"github.com/silenceper/wechat/v2/miniprogram/riskcontrol"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/security"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/shortlink"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/student"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/subscribe"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/tcb"
|
||||
"github.com/silenceper/wechat/v2/miniprogram/urllink"
|
||||
@@ -202,3 +204,13 @@ func (miniProgram *MiniProgram) GetOCR() *ocr.OCR {
|
||||
func (miniProgram *MiniProgram) GetIntracity() *express.Express {
|
||||
return express.NewExpress(miniProgram.ctx)
|
||||
}
|
||||
|
||||
// GetStudent 学生身份核验接口
|
||||
func (miniProgram *MiniProgram) GetStudent() *student.Student {
|
||||
return student.NewStudent(miniProgram.ctx)
|
||||
}
|
||||
|
||||
// GetGeneric 通用 API 调用,用于访问 SDK 尚未封装的接口
|
||||
func (miniProgram *MiniProgram) GetGeneric() *generic.Generic {
|
||||
return generic.NewGeneric(miniProgram.ctx)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package student
|
||||
|
||||
import (
|
||||
context2 "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/miniprogram/context"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// quickCheckStudentIdentityURL 快速获取学生身份
|
||||
quickCheckStudentIdentityURL = "https://api.weixin.qq.com/intp/quickcheckstudentidentity?access_token=%s"
|
||||
)
|
||||
|
||||
// Student 学生身份核验
|
||||
type Student struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
// NewStudent init
|
||||
func NewStudent(ctx *context.Context) *Student {
|
||||
return &Student{ctx}
|
||||
}
|
||||
|
||||
// BindStatus 学生身份绑定状态
|
||||
type BindStatus int
|
||||
|
||||
const (
|
||||
// BindStatusUnbound 未绑定
|
||||
BindStatusUnbound BindStatus = 1
|
||||
// BindStatusAuditing 审核中
|
||||
BindStatusAuditing BindStatus = 2
|
||||
// BindStatusBound 已绑定
|
||||
BindStatusBound BindStatus = 3
|
||||
)
|
||||
|
||||
// QuickCheckStudentIdentityRequest 快速获取学生身份请求参数
|
||||
type QuickCheckStudentIdentityRequest struct {
|
||||
OpenID string `json:"openid"` // 用户在业务方下的openid,需为已开通接口权限小程序对应的用户openid
|
||||
WxStudentCheckCode string `json:"wx_studentcheck_code"` // 用户授权查询code,由授权插件返回,code有效期两小时
|
||||
}
|
||||
|
||||
// QuickCheckStudentIdentityResponse 快速获取学生身份返回参数
|
||||
type QuickCheckStudentIdentityResponse struct {
|
||||
util.CommonError
|
||||
BindStatus BindStatus `json:"bind_status"` // 绑定状态:1-未绑定,2-审核中,3-已绑定
|
||||
IsStudent bool `json:"is_student"` // 用户学生身份绑定状态说明,true-是学生,false-不是学生
|
||||
}
|
||||
|
||||
// QuickCheckStudentIdentity 快速获取学生身份
|
||||
// see https://developers.weixin.qq.com/miniprogram/dev/server/API/student/api_quickcheckstudentidentity.html
|
||||
func (student *Student) QuickCheckStudentIdentity(in *QuickCheckStudentIdentityRequest) (out QuickCheckStudentIdentityResponse, err error) {
|
||||
return student.QuickCheckStudentIdentityContext(context2.Background(), in)
|
||||
}
|
||||
|
||||
// QuickCheckStudentIdentityContext 快速获取学生身份
|
||||
func (student *Student) QuickCheckStudentIdentityContext(ctx context2.Context, in *QuickCheckStudentIdentityRequest) (out QuickCheckStudentIdentityResponse, err error) {
|
||||
var accessToken string
|
||||
if accessToken, err = student.GetAccessTokenContext(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf(quickCheckStudentIdentityURL, accessToken)
|
||||
var response []byte
|
||||
if response, err = util.PostJSONContext(ctx, uri, in); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 使用通用方法返回错误
|
||||
err = util.DecodeWithError(response, &out, "student.QuickCheckStudentIdentity")
|
||||
return
|
||||
}
|
||||
@@ -14,6 +14,24 @@ const (
|
||||
// CustomerBatchGetOptions 客户基本信息获取请求参数
|
||||
type CustomerBatchGetOptions struct {
|
||||
ExternalUserIDList []string `json:"external_userid_list"` // external_userid列表
|
||||
// NeedEnterSessionContext 是否需要返回客户48小时内最后一次进入会话的上下文信息
|
||||
// 0-不返回 1-返回。默认不返回
|
||||
NeedEnterSessionContext int `json:"need_enter_session_context"`
|
||||
}
|
||||
|
||||
// CustomerWechatChannelsSchema 进入会话的视频号信息,从视频号进入会话才有值
|
||||
type CustomerWechatChannelsSchema struct {
|
||||
Nickname string `json:"nickname"` // 视频号名称,视频号场景值为1、2、3时返回此项
|
||||
ShopNickname string `json:"shop_nickname"` // 视频号小店名称,视频号场景值为4、5时返回此项
|
||||
Scene uint32 `json:"scene"` // 视频号场景值。1:视频号主页,2:视频号直播间商品列表页,3:视频号商品橱窗页,4:视频号小店商品详情页,5:视频号小店订单页
|
||||
}
|
||||
|
||||
// CustomerEnterSessionContextSchema 48小时内最后一次进入会话的上下文信息
|
||||
// 请求的need_enter_session_context参数设置为1才返回
|
||||
type CustomerEnterSessionContextSchema struct {
|
||||
Scene string `json:"scene"` // 进入会话的场景值,获取客服账号链接开发者自定义的场景值
|
||||
SceneParam string `json:"scene_param"` // 进入会话的自定义参数,获取客服账号链接返回的url,开发者按规范拼接的scene_param参数
|
||||
WechatChannels CustomerWechatChannelsSchema `json:"wechat_channels"` // 进入会话的视频号信息,从视频号进入会话才有值
|
||||
}
|
||||
|
||||
// CustomerSchema 微信客户基本资料
|
||||
@@ -23,6 +41,9 @@ type CustomerSchema struct {
|
||||
Avatar string `json:"avatar"` // 微信头像。第三方不可获取
|
||||
Gender int `json:"gender"` // 性别
|
||||
UnionID string `json:"unionid"` // unionid,需要绑定微信开发者帐号才能获取到,查看绑定方法: https://open.work.weixin.qq.com/kf/doc/92512/93143/94769#%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E5%BE%AE%E4%BF%A1%E5%AE%A2%E6%88%B7%E7%9A%84unionid
|
||||
// EnterSessionContext 48小时内最后一次进入会话的上下文信息
|
||||
// 请求的need_enter_session_context参数设置为1才返回
|
||||
EnterSessionContext CustomerEnterSessionContextSchema `json:"enter_session_context"`
|
||||
}
|
||||
|
||||
// CustomerBatchGetSchema 获取客户基本信息响应内容
|
||||
|
||||
Reference in new issue
Block a user