2023-08-12 19:04:04 +02:00
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"
2024-07-15 17:26:55 +02:00
"gogs.mikescher.com/BlackForestBytes/goext/ginext"
2023-08-12 19:04:04 +02:00
"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]
2024-07-15 17:26:55 +02:00
func ( h ExternalHandler ) UptimeKuma ( pctx ginext . PreContext ) ginext . HTTPResponse {
2023-08-12 19:04:04 +02:00
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
2024-07-16 17:19:55 +02:00
ctx , g , errResp := pctx . Query ( & q ) . Body ( & b ) . Start ( )
if errResp != nil {
return * errResp
2023-08-12 19:04:04 +02:00
}
defer ctx . Cancel ( )
2024-09-16 15:17:20 +02:00
return h . app . DoRequest ( ctx , g , models . TLockReadWrite , func ( ctx * logic . AppContext , finishSuccess func ( r ginext . HTTPResponse ) ginext . HTTPResponse ) ginext . HTTPResponse {
2024-07-16 17:19:55 +02:00
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 )
}
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
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 ) )
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
content := b . Heartbeat . Msg
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
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 ( ) ) )
}
2023-08-12 19:04:04 +02:00
}
2024-07-16 17:19:55 +02:00
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
}
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
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
}
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
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 ,
} ) )
2023-08-12 19:04:04 +02:00
2024-07-16 17:19:55 +02:00
} )
2023-08-12 19:04:04 +02:00
}