139 lines
4.5 KiB
Go
139 lines
4.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"blackforestbytes.com/simplecloudnotifier/api/apierr"
|
|
"blackforestbytes.com/simplecloudnotifier/api/ginresp"
|
|
primarydb "blackforestbytes.com/simplecloudnotifier/db/impl/primary"
|
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
|
"blackforestbytes.com/simplecloudnotifier/models"
|
|
"fmt"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/ginext"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type ExternalHandler struct {
|
|
app *logic.Application
|
|
database *primarydb.Database
|
|
}
|
|
|
|
func NewExternalHandler(app *logic.Application) ExternalHandler {
|
|
return ExternalHandler{
|
|
app: app,
|
|
database: app.Database.Primary,
|
|
}
|
|
}
|
|
|
|
// UptimeKuma swaggerdoc
|
|
//
|
|
// @Summary Send a new message
|
|
// @Description All parameter can be set via query-parameter or the json body. Only UserID, UserKey and Title are required
|
|
// @Tags External
|
|
//
|
|
// @Param query_data query handler.UptimeKuma.query false " "
|
|
// @Param post_body body handler.UptimeKuma.body false " "
|
|
//
|
|
// @Success 200 {object} handler.UptimeKuma.response
|
|
// @Failure 400 {object} ginresp.apiError
|
|
// @Failure 401 {object} ginresp.apiError "The user_id was not found or the user_key is wrong"
|
|
// @Failure 403 {object} ginresp.apiError "The user has exceeded its daily quota - wait 24 hours or upgrade your account"
|
|
// @Failure 500 {object} ginresp.apiError "An internal server error occurred - try again later"
|
|
//
|
|
// @Router /external/v1/uptime-kuma [POST]
|
|
func (h ExternalHandler) UptimeKuma(pctx ginext.PreContext) ginext.HTTPResponse {
|
|
type query struct {
|
|
UserID *models.UserID `form:"user_id" example:"7725"`
|
|
KeyToken *string `form:"key" example:"P3TNH8mvv14fm"`
|
|
Channel *string `form:"channel"`
|
|
ChannelUp *string `form:"channel_up"`
|
|
ChannelDown *string `form:"channel_down"`
|
|
Priority *int `form:"priority"`
|
|
PriorityUp *int `form:"priority_up"`
|
|
PriorityDown *int `form:"priority_down"`
|
|
SenderName *string `form:"senderName"`
|
|
}
|
|
type body struct {
|
|
Heartbeat *struct {
|
|
Time string `json:"time"`
|
|
Status int `json:"status"`
|
|
Msg string `json:"msg"`
|
|
Timezone string `json:"timezone"`
|
|
TimezoneOffset string `json:"timezoneOffset"`
|
|
LocalDateTime string `json:"localDateTime"`
|
|
} `json:"heartbeat"`
|
|
Monitor *struct {
|
|
Name string `json:"name"`
|
|
Url *string `json:"url"`
|
|
} `json:"monitor"`
|
|
Msg *string `json:"msg"`
|
|
}
|
|
type response struct {
|
|
MessageID models.MessageID `json:"message_id"`
|
|
}
|
|
|
|
var b body
|
|
var q query
|
|
ctx, g, errResp := pctx.Query(&q).Body(&b).Start()
|
|
if errResp != nil {
|
|
return *errResp
|
|
}
|
|
defer ctx.Cancel()
|
|
|
|
return h.app.DoRequest(ctx, g, models.TLockReadWrite, func(ctx *logic.AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
|
|
|
|
if b.Heartbeat == nil {
|
|
return ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "missing field 'heartbeat' in request body", nil)
|
|
}
|
|
if b.Monitor == nil {
|
|
return ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "missing field 'monitor' in request body", nil)
|
|
}
|
|
if b.Msg == nil {
|
|
return ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "missing field 'msg' in request body", nil)
|
|
}
|
|
|
|
title := langext.Conditional(b.Heartbeat.Status == 1, fmt.Sprintf("Monitor %v is back online", b.Monitor.Name), fmt.Sprintf("Monitor %v went down!", b.Monitor.Name))
|
|
|
|
content := b.Heartbeat.Msg
|
|
|
|
var timestamp *float64 = nil
|
|
if tz, err := time.LoadLocation(b.Heartbeat.Timezone); err == nil {
|
|
if ts, err := time.ParseInLocation("2006-01-02 15:04:05", b.Heartbeat.LocalDateTime, tz); err == nil {
|
|
timestamp = langext.Ptr(float64(ts.Unix()))
|
|
}
|
|
}
|
|
|
|
var channel *string = nil
|
|
if q.Channel != nil {
|
|
channel = q.Channel
|
|
}
|
|
if q.ChannelUp != nil && b.Heartbeat.Status == 1 {
|
|
channel = q.ChannelUp
|
|
}
|
|
if q.ChannelDown != nil && b.Heartbeat.Status != 1 {
|
|
channel = q.ChannelDown
|
|
}
|
|
|
|
var priority *int = nil
|
|
if q.Priority != nil {
|
|
priority = q.Priority
|
|
}
|
|
if q.PriorityUp != nil && b.Heartbeat.Status == 1 {
|
|
priority = q.PriorityUp
|
|
}
|
|
if q.PriorityDown != nil && b.Heartbeat.Status != 1 {
|
|
priority = q.PriorityDown
|
|
}
|
|
|
|
okResp, errResp := h.app.SendMessage(g, ctx, q.UserID, q.KeyToken, channel, &title, &content, priority, nil, timestamp, q.SenderName)
|
|
if errResp != nil {
|
|
return *errResp
|
|
}
|
|
|
|
return finishSuccess(ginext.JSON(http.StatusOK, response{
|
|
MessageID: okResp.Message.MessageID,
|
|
}))
|
|
|
|
})
|
|
}
|