Notify push test

This commit is contained in:
yoan
2024-10-19 18:12:45 +08:00
parent 4382474449
commit 7fa6ea1797
19 changed files with 929 additions and 254 deletions

23
internal/domain/err.go Normal file
View File

@@ -0,0 +1,23 @@
package domain
var ErrAuthFailed = NewXError(4999, "auth failed")
type XError struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func NewXError(code int, msg string) *XError {
return &XError{code, msg}
}
func (e *XError) Error() string {
return e.Msg
}
func (e *XError) GetCode() int {
if e.Code == 0 {
return 100
}
return e.Code
}

12
internal/domain/notify.go Normal file
View File

@@ -0,0 +1,12 @@
package domain
const (
NotifyChannelDingtalk = "dingtalk"
NotifyChannelWebhook = "webhook"
NotifyChannelTelegram = "telegram"
NotifyChannelLark = "lark"
)
type NotifyTestPushReq struct {
Channel string `json:"channel"`
}

View File

@@ -0,0 +1,31 @@
package domain
import (
"encoding/json"
"fmt"
"time"
)
type Setting struct {
ID string `json:"id"`
Name string `json:"name"`
Content string `json:"content"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
}
type ChannelsConfig map[string]map[string]any
func (s *Setting) GetChannelContent(channel string) (map[string]any, error) {
conf := &ChannelsConfig{}
if err := json.Unmarshal([]byte(s.Content), conf); err != nil {
return nil, err
}
v, ok := (*conf)[channel]
if !ok {
return nil, fmt.Errorf("channel %s not found", channel)
}
return v, nil
}

View File

@@ -1,11 +1,13 @@
package notify
import (
"certimate/internal/utils/app"
"context"
"fmt"
"strconv"
"certimate/internal/domain"
"certimate/internal/utils/app"
notifyPackage "github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/dingding"
"github.com/nikoksr/notify/service/http"
@@ -13,13 +15,6 @@ import (
"github.com/nikoksr/notify/service/telegram"
)
const (
notifyChannelDingtalk = "dingtalk"
notifyChannelWebhook = "webhook"
notifyChannelTelegram = "telegram"
notifyChannelLark = "lark"
)
func Send(title, content string) error {
// 获取所有的推送渠道
notifiers, err := getNotifiers()
@@ -38,6 +33,28 @@ func Send(title, content string) error {
return n.Send(context.Background(), title, content)
}
type sendTestParam struct {
Title string `json:"title"`
Content string `json:"content"`
Channel string `json:"channel"`
Conf map[string]any `json:"conf"`
}
func SendTest(param *sendTestParam) error {
notifier, err := getNotifier(param.Channel, param.Conf)
if err != nil {
return err
}
n := notifyPackage.New()
// 添加推送渠道
n.UseServices(notifier)
// 发送消息
return n.Send(context.Background(), param.Title, param.Content)
}
func getNotifiers() ([]notifyPackage.Notifier, error) {
resp, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='notifyChannels'")
if err != nil {
@@ -58,27 +75,38 @@ func getNotifiers() ([]notifyPackage.Notifier, error) {
continue
}
switch k {
case notifyChannelTelegram:
temp := getTelegramNotifier(v)
if temp == nil {
continue
}
notifiers = append(notifiers, temp)
case notifyChannelDingtalk:
notifiers = append(notifiers, getDingTalkNotifier(v))
case notifyChannelLark:
notifiers = append(notifiers, getLarkNotifier(v))
case notifyChannelWebhook:
notifiers = append(notifiers, getWebhookNotifier(v))
notifier, err := getNotifier(k, v)
if err != nil {
continue
}
notifiers = append(notifiers, notifier)
}
return notifiers, nil
}
func getNotifier(channel string, conf map[string]any) (notifyPackage.Notifier, error) {
switch channel {
case domain.NotifyChannelTelegram:
temp := getTelegramNotifier(conf)
if temp == nil {
return nil, fmt.Errorf("telegram notifier config error")
}
return temp, nil
case domain.NotifyChannelDingtalk:
return getDingTalkNotifier(conf), nil
case domain.NotifyChannelLark:
return getLarkNotifier(conf), nil
case domain.NotifyChannelWebhook:
return getWebhookNotifier(conf), nil
}
return nil, fmt.Errorf("notifier not found")
}
func getWebhookNotifier(conf map[string]any) notifyPackage.Notifier {
rs := http.New()

View File

@@ -0,0 +1,46 @@
package notify
import (
"context"
"fmt"
"certimate/internal/domain"
)
const (
notifyTestTitle = "测试通知"
notifyTestBody = "欢迎使用 Certimate ,这是一条测试通知。"
)
type SettingRepository interface {
GetByName(ctx context.Context, name string) (*domain.Setting, error)
}
type NotifyService struct {
settingRepo SettingRepository
}
func NewNotifyService(settingRepo SettingRepository) *NotifyService {
return &NotifyService{
settingRepo: settingRepo,
}
}
func (n *NotifyService) Test(ctx context.Context, req *domain.NotifyTestPushReq) error {
setting, err := n.settingRepo.GetByName(ctx, "notifyChannels")
if err != nil {
return fmt.Errorf("get notify channels setting failed: %w", err)
}
conf, err := setting.GetChannelContent(req.Channel)
if err != nil {
return fmt.Errorf("get notify channel %s config failed: %w", req.Channel, err)
}
return SendTest(&sendTestParam{
Title: notifyTestTitle,
Content: notifyTestBody,
Channel: req.Channel,
Conf: conf,
})
}

View File

@@ -0,0 +1,31 @@
package repository
import (
"context"
"certimate/internal/domain"
"certimate/internal/utils/app"
)
type SettingRepository struct{}
func NewSettingRepository() *SettingRepository {
return &SettingRepository{}
}
func (s *SettingRepository) GetByName(ctx context.Context, name string) (*domain.Setting, error) {
resp, err := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='"+name+"'")
if err != nil {
return nil, err
}
rs := &domain.Setting{
ID: resp.GetString("id"),
Name: resp.GetString("name"),
Content: resp.GetString("content"),
Created: resp.GetTime("created"),
Updated: resp.GetTime("updated"),
}
return rs, nil
}

41
internal/rest/notify.go Normal file
View File

@@ -0,0 +1,41 @@
package rest
import (
"context"
"certimate/internal/domain"
"certimate/internal/utils/resp"
"github.com/labstack/echo/v5"
)
type NotifyService interface {
Test(ctx context.Context, req *domain.NotifyTestPushReq) error
}
type notifyHandler struct {
service NotifyService
}
func NewNotifyHandler(route *echo.Group, service NotifyService) {
handler := &notifyHandler{
service: service,
}
group := route.Group("/notify")
group.POST("/test", handler.test)
}
func (handler *notifyHandler) test(c echo.Context) error {
req := &domain.NotifyTestPushReq{}
if err := c.Bind(req); err != nil {
return err
}
if err := handler.service.Test(c.Request().Context(), req); err != nil {
return resp.Err(c, err)
}
return resp.Succ(c, nil)
}

19
internal/routes/routes.go Normal file
View File

@@ -0,0 +1,19 @@
package routes
import (
"certimate/internal/notify"
"certimate/internal/repository"
"certimate/internal/rest"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/apis"
)
func Register(e *echo.Echo) {
notifyRepo := repository.NewSettingRepository()
notifySvc := notify.NewNotifyService(notifyRepo)
group := e.Group("/api", apis.RequireAdminAuth())
rest.NewNotifyHandler(group, notifySvc)
}

View File

@@ -0,0 +1,39 @@
package resp
import (
"net/http"
"certimate/internal/domain"
"github.com/labstack/echo/v5"
)
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
func Succ(e echo.Context, data interface{}) error {
rs := &Response{
Code: 0,
Msg: "success",
Data: data,
}
return e.JSON(http.StatusOK, rs)
}
func Err(e echo.Context, err error) error {
xerr, ok := err.(*domain.XError)
code := 100
if ok {
code = xerr.GetCode()
}
rs := &Response{
Code: code,
Msg: err.Error(),
Data: nil,
}
return e.JSON(http.StatusOK, rs)
}