都在秀新写的消息推送工具。我炒个冷饭。bark 的批量推送。。。

2021-03-29 11:15:25 +08:00
 zpfhbyx

由于过于简单。没有项目。。自己用 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 的默认值咋写。现在是最后的方法拼凑的。

1901 次点击
所在节点    分享创造
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/766087

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX