由于过于简单。没有项目。。自己用 gin 套一下。。
package services
import (
"encoding/json"
"fmt"
"github.com/go-resty/resty/v2"
"net/http"
"sync"
"time"
)
var BarkApiHost = "http://172.17.0.3:8080"
type BarkApi struct {
request *resty.Client
}
type BarkPushForm struct {
Devices []Device `json:"devices" binding:"required"`
Message Message `json:"message" binding:"required"`
}
type Device struct {
DeviceId string `json:"device_id" binding:"required"`
Host string `json:"host"`
}
type Message struct {
Title string `json:"title"`
Body string `json:"body"`
Category string `json:"category"`
}
type BarkRestResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
var (
barkInstance *BarkApi
barkOnce sync.Once
)
func GetBarkInstance() *BarkApi {
barkOnce.Do(func() {
barkInstance = &BarkApi{
request: resty.New().SetTimeout(2 * time.Second).OnError(func(request *resty.Request, err error) {
fmt.Println(err)
}),
}
})
return barkInstance
}
func (bark BarkApi) Push(devices []Device, message Message) map[string]string {
var wg sync.WaitGroup
resChan := make(chan map[string]string, len(devices))
defer close(resChan)
for _, device := range devices {
wg.Add(1)
go bark.asyncPush(device, message, &wg, resChan)
}
wg.Wait()
returnRes := map[string]string{}
for i := 0; i < len(devices); i++ {
res := <-resChan
for k, v := range res {
returnRes[k] = v
}
}
return returnRes
}
func (bark BarkApi) asyncPush(device Device, message Message, wg *sync.WaitGroup, resChan chan map[string]string) bool {
defer wg.Done()
resp, err := bark.request.R().SetFormData(map[string]string{
"title": message.Title,
"body": message.Body,
"category": message.Category,
}).Post(bark.getFullPath(fmt.Sprintf("/%s/", device.DeviceId), device.Host))
var pushStatus string = "success"
if err != nil {
resChan <- map[string]string{device.DeviceId: err.Error()}
return false
}
if resp.StatusCode() != http.StatusOK {
resChan <- map[string]string{device.DeviceId: fmt.Sprintf("%d", resp.StatusCode())}
return false
}
var respJson BarkRestResponse
if err := json.Unmarshal(resp.Body(), &respJson); err != nil {
resChan <- map[string]string{device.DeviceId: err.Error()}
return false
}
if respJson.Code != http.StatusOK {
resChan <- map[string]string{device.DeviceId: respJson.Message}
return false
}
resChan <- map[string]string{device.DeviceId: pushStatus}
return true
}
func (bark BarkApi) getFullPath(path string, host string) string {
lastHost := BarkApiHost
if host != "" {
lastHost = host
}
return fmt.Sprintf("%s%s", lastHost, path)
}
json 结构如下:
{
"devices":[
{
"device_id":"device_id",
"host":"该 device_id 所属服务"
},
{
"device_id":"device_id",
"host":"该 device_id 所属服务"
}
],
"message":{
"title":"test",
"body":"123123",
"category":"123123"
}
}
响应
{
"code": 200,
"data": {
"device_id": "success"
},
"message": "success"
}
{
"code": 200,
"data": {
"device_id": "找不到 Key 对应的 DeviceToken, 请确保 Key 正确! Key 可在 App 端注册获得。"
},
"message": "success"
}
ps: 请教一下。device.host 的默认值咋写。现在是最后的方法拼凑的。