update service

master
李光春 2 years ago
parent 0661b4bd33
commit 0ebf74ce62

@ -1,26 +0,0 @@
package wechatminiprogram
import (
"encoding/json"
"fmt"
)
// GetTicketResult 返回参数
type GetTicketResult struct {
Errcode int `json:"errcode"` // 错误码
Errmsg string `json:"errmsg"` // 错误信息
Ticket string `json:"ticket"`
ExpiresIn int `json:"expires_in"`
}
func (app *App) GetTicket(accessToken, Type string) (result GetTicketResult, err error) {
// request
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=%s", accessToken, Type), map[string]interface{}{}, "GET")
if err != nil {
return
}
if err = json.Unmarshal(body, &result); err != nil {
return
}
return
}

@ -1,13 +0,0 @@
package wechatminiprogram
import (
"fmt"
)
func (app *App) MessageTemplateSend(notMustParams ...Params) (body []byte, err error) {
// 参数
params := app.NewParamsWith(notMustParams...)
// 请求
body, err = app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", app.AccessToken), params, "POST")
return
}

@ -1,75 +0,0 @@
package wechatminiprogram
import (
"encoding/json"
"fmt"
"log"
"net/url"
)
// Oauth2 用户同意授权获取code
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
func (app *App) Oauth2(redirectUri, state string) string {
param := url.Values{}
param.Add("appid", app.AppId) // 公众号的唯一标识
param.Add("redirect_uri", redirectUri) // 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
param.Add("response_type", "code") // 返回类型
param.Add("scope", "snsapi_userinfo") // 应用授权作用域
param.Add("state", state) // 重定向后会带上state参数开发者可以填写a-zA-Z0-9的参数值最多128字节
log.Println(fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?%s#wechat_redirect", param.Encode()))
return fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?%s#wechat_redirect", param.Encode())
}
// Oauth2AccessTokenResult 返回参数
type Oauth2AccessTokenResult struct {
AccessToken string `json:"access_token"` // 网页授权接口调用凭证,注意此access_token与基础支持的access_token不同
ExpiresIn int `json:"expires_in"` // access_token接口调用凭证超时时间单位
RefreshToken string `json:"refresh_token"` // 用户刷新access_token
Openid string `json:"openid"` // 用户唯一标识
Scope string `json:"scope"` // 用户授权的作用域,使用逗号(,)分隔
}
// Oauth2AccessToken 通过code换取网页授权access_token
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
func (app *App) Oauth2AccessToken(code string) (result Oauth2AccessTokenResult, err error) {
// 请求
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", app.AppId, app.AppSecret, code), map[string]interface{}{}, "GET")
if err != nil {
return result, err
}
// 解析
err = json.Unmarshal(body, &result)
if err != nil {
return result, err
}
return result, err
}
// Oauth2UserinfoResult 返回参数
type Oauth2UserinfoResult struct {
Openid string `json:"openid"` // 用户的唯一标识
Nickname string `json:"nickname"` // 用户昵称
Sex int `json:"sex"` // 用户的性别值为1时是男性值为2时是女性值为0时是未知
Province string `json:"province"` // 用户个人资料填写的省份
City string `json:"city"` // 普通用户个人资料填写的城市
Country string `json:"country"` // 国家如中国为CN
Headimgurl string `json:"headimgurl"` // 用户头像最后一个数值代表正方形头像大小有0、46、64、96、132数值可选0代表640*640正方形头像用户没有头像时该项为空。若用户更换头像原有头像URL将失效。
Privilege []string `json:"privilege"` // 用户特权信息json 数组如微信沃卡用户为chinaunicom
Unionid string `json:"unionid,omitempty"` // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
}
// Oauth2Userinfo 拉取用户信息(需scope为 snsapi_userinfo)
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
func (app *App) Oauth2Userinfo(accessToken, openid string) (result Oauth2UserinfoResult, err error) {
// 请求
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", accessToken, openid), map[string]interface{}{}, "GET")
if err != nil {
return result, err
}
// 解析
err = json.Unmarshal(body, &result)
if err != nil {
return result, err
}
return result, err
}

@ -3,6 +3,7 @@ package wechatminiprogram
import (
"encoding/json"
"fmt"
"net/http"
)
// SubscribeMessageSend 入参
@ -21,6 +22,8 @@ type SubscribeMessageSendResult struct {
Errmsg string // 错误信息
}
// SubscribeMessageSend 发送订阅消息
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
func (app *App) SubscribeMessageSend(param SubscribeMessageSend) (result SubscribeMessageSendResult, err error) {
// api params
params := map[string]interface{}{}
@ -32,7 +35,7 @@ func (app *App) SubscribeMessageSend(param SubscribeMessageSend) (result Subscri
}
// request
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s", app.AccessToken), params, "POST")
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s", app.AccessToken), params, http.MethodPost)
if err != nil {
return
}

@ -13,6 +13,8 @@ type GetTicketResult struct {
ExpiresIn int `json:"expires_in"`
}
// GetTicket 获取api_ticket
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
func (app *App) GetTicket(accessToken, Type string) (result GetTicketResult, err error) {
// request
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=%s", accessToken, Type), map[string]interface{}{}, "GET")

@ -2,12 +2,15 @@ package wechatoffice
import (
"fmt"
"net/http"
)
// MessageTemplateSend 模板消息
// https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
func (app *App) MessageTemplateSend(notMustParams ...Params) (body []byte, err error) {
// 参数
params := app.NewParamsWith(notMustParams...)
// 请求
body, err = app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", app.AccessToken), params, "POST")
body, err = app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", app.AccessToken), params, http.MethodPost)
return
}

@ -1,43 +0,0 @@
package wechatoffice
import (
"encoding/json"
"fmt"
)
// SubscribeMessageSend 入参
type SubscribeMessageSend struct {
Touser string `json:"touser"` // 接收者(用户)的 openid
TemplateId string `json:"template_id"` // 所需下发的订阅模板id
Page string `json:"page,omitempty"` // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,示例index?foo=bar。该字段不填则模板无跳转。
Data map[string]interface{} `json:"data"` // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
MiniprogramState string `json:"miniprogram_state,omitempty"` // 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版
Lang string `json:"lang,omitempty"` // 进入小程序查看”的语言类型支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文)默认为zh_CN
}
// SubscribeMessageSendResult 返回参数
type SubscribeMessageSendResult struct {
Errcode int // 错误码
Errmsg string // 错误信息
}
func (app *App) SubscribeMessageSend(param SubscribeMessageSend) (result SubscribeMessageSendResult, err error) {
// api params
params := map[string]interface{}{}
b, _ := json.Marshal(&param)
var m map[string]interface{}
_ = json.Unmarshal(b, &m)
for k, v := range m {
params[k] = v
}
// request
body, err := app.request(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s", app.AccessToken), params, "POST")
if err != nil {
return
}
if err = json.Unmarshal(body, &result); err != nil {
return
}
return
}

@ -1,66 +0,0 @@
package wechatoffice
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json"
"errors"
)
// UserInfo 请求参数
type UserInfo struct {
SessionKey string `json:"session_key"`
EncryptedData string `json:"encrypted_data"`
Iv string `json:"iv"`
}
// UserInfoResult 返回参数
type UserInfoResult struct {
OpenID string `json:"openId"`
NickName string `json:"nickName"`
Gender int `json:"gender"`
City string `json:"city"`
Province string `json:"province"`
Country string `json:"country"`
AvatarUrl string `json:"avatarUrl"`
UnionId string `json:"unionId"`
Watermark struct {
AppID string `json:"appid"`
Timestamp int64 `json:"timestamp"`
} `json:"watermark"`
}
// UserInfo 解密用户信息
func (app *App) UserInfo(param UserInfo) (result UserInfoResult, err error) {
aesKey, err := base64.StdEncoding.DecodeString(param.SessionKey)
if err != nil {
return result, err
}
cipherText, err := base64.StdEncoding.DecodeString(param.EncryptedData)
if err != nil {
return result, err
}
ivBytes, err := base64.StdEncoding.DecodeString(param.Iv)
if err != nil {
return result, err
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
mode := cipher.NewCBCDecrypter(block, ivBytes)
mode.CryptBlocks(cipherText, cipherText)
cipherText, err = app.pkcs7Unpaid(cipherText, block.BlockSize())
if err != nil {
return result, err
}
err = json.Unmarshal(cipherText, &result)
if err != nil {
return result, err
}
if result.Watermark.AppID != app.AppId {
return result, errors.New("app id not match")
}
return result, nil
}

@ -1,61 +0,0 @@
package wechatoffice
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json"
"errors"
)
// UserPhone 请求参数
type UserPhone struct {
SessionKey string `json:"session_key"`
EncryptedData string `json:"encrypted_data"`
Iv string `json:"iv"`
}
// UserPhoneResult 返回参数
type UserPhoneResult struct {
PhoneNumber string `json:"phoneNumber"` // 用户绑定的手机号(国外手机号会有区号)
PurePhoneNumber string `json:"purePhoneNumber"` // 没有区号的手机号
CountryCode string `json:"countryCode"` // 区号
Watermark struct {
AppID string `json:"appid"`
Timestamp int64 `json:"timestamp"`
} `json:"watermark"`
}
// UserPhone 解密手机号信息
func (app *App) UserPhone(param UserPhone) (result UserPhoneResult, err error) {
aesKey, err := base64.StdEncoding.DecodeString(param.SessionKey)
if err != nil {
return result, err
}
cipherText, err := base64.StdEncoding.DecodeString(param.EncryptedData)
if err != nil {
return result, err
}
ivBytes, err := base64.StdEncoding.DecodeString(param.Iv)
if err != nil {
return result, err
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
mode := cipher.NewCBCDecrypter(block, ivBytes)
mode.CryptBlocks(cipherText, cipherText)
cipherText, err = app.pkcs7Unpaid(cipherText, block.BlockSize())
if err != nil {
return result, err
}
err = json.Unmarshal(cipherText, &result)
if err != nil {
return result, err
}
if result.Watermark.AppID != app.AppId {
return result, errors.New("app id not match")
}
return result, nil
}
Loading…
Cancel
Save