事情並不簡單
開發須要用到釘釘開放平臺提供的接口,可是釘釘官方並無提供 Go 語言版本的 sdkgit
在 GitHub 逛了一圈後,找不到滿意的開源版本,有些 repo 設計不太規範,有些 repo 只實現了部分功能github
因而,我決定親手擼一個web
但很快,我就發現事情並不簡單:釘釘開放平臺提供了超過 200 個接口!c#
開發一個完整的 sdk 須要閱讀每個接口的文檔,理解各個參數的做用,處理各類異常和接口返回的結果,還有 access_token 管理、數據加解密等細節api
即便是資深開發工程師,在這髒活累活上,恐怕也得耗上半個月的時間服務器
太慢了,這不是我想要的微信
快就一個字
通過 30 分鐘仔細閱讀接口文檔後,我發現了一些規律:架構
-
服務器地址都是 https://oapi.dingtalk.com/ -
HTTP 請求方法都是 POST 或 GET -
全部的請求都須要 access_token 參數 -
官方文檔針對每個接口都詳細列出了接口簡介、接口地址、Query 參數、Body 參數 -
...
一個不太成熟的小想法就浮現出腦海:app
-
搞個爬蟲抓取接口名稱、接口簡介、接口地址、Query 參數、Body 參數 等 API 元信息 -
一個 API 的規格由其元信息惟必定義 -
每一個 API 都由一個 func
表示 -
用 params url.Values
表示接口須要的Query 參數 -
用 payload []byte
表示接口須要的Body 參數 -
用 resp []byte
表示接口的返回內容 -
根據 API 分組狀況,拆分 package -
全部 API 請求由統一的 Http Client 模塊處理 -
access_token、錯誤處理和重試邏輯由 Http Client 模塊處理 -
釘釘服務器發出回調由 Http Server 模塊處理 -
...
至此,一個簡潔但完整的架構呼之欲出:編輯器
咱們將打造這樣一款 sdk : 介於業務邏輯 和 釘釘 之間,將業務的指令發送到釘釘,將釘釘的響應透傳給業務
魔鬼在細節
按照上 part 咱們的構想,就能夠開始搞了
先看看釘釘文檔頁面結構:
啓動爬蟲抓回來接口元信息:
Api{
Name: "獲取用戶userid",
Description: "經過免登受權碼和access_token獲取用戶的userid。",
Request: "GET https://oapi.dingtalk.com/user/getuserinfo?access_token=access_token&code=code",
See: "https://ding-doc.dingtalk.com/doc#/serverapi2/clotub",
FuncName: "GetUserInfo",
GetParams: []Param{
{Name: `code`, Type: `string`},
},
}
格式化成 Go func
:
package auth
import ...
const apiGetUserInfo = "/user/getuserinfo"
/*
獲取用戶userid
經過免登受權碼和access_token獲取用戶的userid。
See: https://ding-doc.dingtalk.com/doc#/serverapi2/clotub
GET https://oapi.dingtalk.com/user/getuserinfo?access_token=access_token&code=code
*/
func GetUserInfo(ctx *dingding.App, params url.Values) (resp []byte, err error) {
return ctx.Client.HTTPGet(apiGetUserInfo + "?" + params.Encode())
}
再搞個 test
和 example
的模板代碼,當爬蟲所有執行完後,咱們就能夠獲得:
├─ai
│ ai.go
│ ai_test.go
│ example_ai_test.go
│
├─alitrip
│ alitrip.go
│ alitrip_test.go
│ example_alitrip_test.go
│
├─attendance
│ attendance.go
│ attendance_test.go
│ example_attendance_test.go
│
......
Wow Amazing! 200 個接口已盡入吾彀中矣
不過,咱們時間很少了:
-
部分接口文檔頁面不規範,致使爬蟲中斷了 20 分鐘 -
GET|POST 不一樣類型的請求測試函數的差別比較大,耗費了 40 分鐘 -
...
access_token 管理
全部接口調用最終都由統一的 Http Client 模塊發起
因爲每一個接口調用都須要鑑權,因此咱們把鑑權模塊放在這裏再好不過了
處理方式很是簡單,拿到access_token
,加到請求地址後便可:
accessToken, _ := client.Ctx.AccessToken.GetAccessTokenHandler()
newUrl := url + "?access_token=" + accessToken
關鍵在 GetAccessTokenHandler
方法,這裏定義瞭如何獲取 access_token
試一試
再處理一下其餘細節,包括錯誤處理、單元測試等,咱們的 sdk 就差很少搞定啦
如今到了 Eating your own dog food
環節:
go get github.com/fastwego/dingding
// 建立應用實例
app := dingding.NewApp(dingding.AppConfig{
AppKey: viper.GetString("AppKey"),
AppSecret: viper.GetString("AppSecret"),
})
// 調用 api
params := url.Values{}
params.Add("code", CODE)
resp, err := auth.GetUserInfo(app, params)
若是一切正常的話,接口能夠正確響應咱們的請求
效果好極啦,調用簡單,不只有 Example 引導,還有文檔和連接:
果真仍是本身打造的工具最趁手
纔剛剛開始
在一樣的思路下,我又擼完了企業微信和飛書的 Go sdk
-
https://github.com/fastwego/wxwork -
https://github.com/fastwego/feishu
to be continue ...
本文分享自微信公衆號 - 追馬Linux(zhuima_k8s)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。