ai_scheduler/internal/pkg/dingtalk/client.go

106 lines
2.5 KiB
Go

package dingtalk
import (
"ai_scheduler/internal/config"
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"os"
"github.com/faabiosr/cachego/file"
"github.com/fastwego/dingding"
)
type Client struct {
cfg *config.Config
sdkClient *dingding.Client
}
func NewDingTalkClient(cfg *config.Config) *Client {
atm := &dingding.DefaultAccessTokenManager{
Id: cfg.Tools.DingTalkBot.APIKey,
Name: "access_token",
GetRefreshRequestFunc: func() *http.Request {
params := url.Values{}
params.Add("appkey", cfg.Tools.DingTalkBot.APIKey)
params.Add("appsecret", cfg.Tools.DingTalkBot.APISecret)
req, _ := http.NewRequest(http.MethodGet, dingding.ServerUrl+"/gettoken?"+params.Encode(), nil)
return req
},
Cache: file.New(os.TempDir()),
}
return &Client{cfg: cfg, sdkClient: dingding.NewClient(atm)}
}
type UserDetail struct {
UserID string `json:"userid"`
Name string `json:"name"`
UnionID string `json:"unionid"`
}
func (c *Client) do(ctx context.Context, method, path string, body []byte) ([]byte, error) {
var r io.Reader
if body != nil {
r = bytes.NewReader(body)
}
req, err := http.NewRequestWithContext(ctx, method, path, r)
if err != nil {
return nil, err
}
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
return c.sdkClient.Do(req)
}
func (c *Client) QueryUserDetails(ctx context.Context, userId string) (*UserDetail, error) {
body := struct {
UserId string `json:"userid"`
Language string `json:"language,omitempty"`
}{UserId: userId, Language: "zh_CN"}
b, _ := json.Marshal(body)
res, err := c.do(ctx, http.MethodPost, "/topapi/v2/user/get", b)
if err != nil {
return nil, err
}
var resp struct {
Code int `json:"errcode"`
Msg string `json:"errmsg"`
Result UserDetail `json:"result"`
}
if err := json.Unmarshal(res, &resp); err != nil {
return nil, err
}
if resp.Code != 0 {
return nil, errors.New(resp.Msg)
}
return &resp.Result, nil
}
func (c *Client) QueryUserDetailsByMobile(ctx context.Context, mobile string) (*UserDetail, error) {
body := struct {
Mobile string `json:"mobile"`
}{Mobile: mobile}
b, _ := json.Marshal(body)
res, err := c.do(ctx, http.MethodPost, "/topapi/v2/user/getbymobile", b)
if err != nil {
return nil, err
}
var resp struct {
Code int `json:"errcode"`
Msg string `json:"errmsg"`
Result UserDetail `json:"result"`
}
if err := json.Unmarshal(res, &resp); err != nil {
return nil, err
}
if resp.Code != 0 {
return nil, errors.New(resp.Msg)
}
return &resp.Result, nil
}