diff --git a/server/README.md b/server/README.md index efdc297..a85da0c 100644 --- a/server/README.md +++ b/server/README.md @@ -17,3 +17,7 @@ - tests - deploy + + - in my script: use (backupname || hostname) for sendername + + \ No newline at end of file diff --git a/server/api/apierr/enums.go b/server/api/apierr/enums.go index cf9af6f..739611b 100644 --- a/server/api/apierr/enums.go +++ b/server/api/apierr/enums.go @@ -25,6 +25,7 @@ const ( CONTENT_TOO_LONG APIError = 1203 USR_MSG_ID_TOO_LONG APIError = 1204 TIMESTAMP_OUT_OF_RANGE APIError = 1205 + SENDERNAME_TOO_LONG APIError = 1206 USER_NOT_FOUND APIError = 1301 CLIENT_NOT_FOUND APIError = 1302 diff --git a/server/api/handler/api.go b/server/api/handler/api.go index b9a20f8..c41178f 100644 --- a/server/api/handler/api.go +++ b/server/api/handler/api.go @@ -8,14 +8,11 @@ import ( "blackforestbytes.com/simplecloudnotifier/logic" "blackforestbytes.com/simplecloudnotifier/models" "database/sql" - "fmt" "github.com/gin-gonic/gin" "gogs.mikescher.com/BlackForestBytes/goext/langext" "gogs.mikescher.com/BlackForestBytes/goext/mathext" - "gogs.mikescher.com/BlackForestBytes/goext/timeext" "net/http" "strings" - "time" ) type APIHandler struct { @@ -1132,7 +1129,7 @@ func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse { PageSize *int `form:"page_size"` NextPageToken *string `form:"next_page_token"` Filter *string `form:"filter"` - Trimmed *bool `form:"trimmed"` + Trimmed *bool `form:"trimmed"` //TODO more filter (sender-name, channel, timestamps, prio, ) } type response struct { Messages []models.MessageJSON `json:"messages"` @@ -1312,167 +1309,3 @@ func (h APIHandler) DeleteMessage(g *gin.Context) ginresp.HTTPResponse { return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, msg.FullJSON())) } - -// CreateMessage swaggerdoc -// -// @Summary Create a new message -// @Description This is similar to the main route `POST -> https://scn.blackfrestbytes.com/` -// @Description But this route can change in the future, for long-living scripts etc. it's better to use the normal POST route -// @ID api-messages-create -// @Tags API-v2 -// -// @Param post_data query handler.CreateMessage.body false " " -// -// @Success 200 {object} models.MessageJSON -// @Failure 400 {object} ginresp.apiError -// @Failure 401 {object} ginresp.apiError -// @Failure 404 {object} ginresp.apiError -// @Failure 500 {object} ginresp.apiError -// -// @Router /api/messages [POST] -func (h APIHandler) CreateMessage(g *gin.Context) ginresp.HTTPResponse { - type body struct { - Channel *string `json:"channel"` - ChanKey *string `json:"chan_key"` - Title *string `json:"title"` - Content *string `json:"content"` - Priority *int `json:"priority"` - UserMessageID *string `json:"msg_id"` - SendTimestamp *float64 `json:"timestamp"` - } - - var b body - ctx, errResp := h.app.StartRequest(g, nil, nil, &b, nil) - if errResp != nil { - return *errResp - } - defer ctx.Cancel() - - if permResp := ctx.CheckPermissionSend(); permResp != nil { - return *permResp - } - - userID := *ctx.GetPermissionUserID() - - if b.Title != nil { - b.Title = langext.Ptr(strings.TrimSpace(*b.Title)) - } - if b.UserMessageID != nil { - b.UserMessageID = langext.Ptr(strings.TrimSpace(*b.UserMessageID)) - } - - if b.Title == nil { - return ginresp.APIError(g, 400, apierr.MISSING_TITLE, "Missing parameter [[title]]", nil) - } - if b.SendTimestamp != nil && mathext.Abs(*b.SendTimestamp-float64(time.Now().Unix())) > (24*time.Hour).Seconds() { - return ginresp.SendAPIError(g, 400, apierr.TIMESTAMP_OUT_OF_RANGE, -1, "The timestamp mus be within 24 hours of now()", nil) - } - if b.Priority != nil && (*b.Priority != 0 && *b.Priority != 1 && *b.Priority != 2) { - return ginresp.SendAPIError(g, 400, apierr.INVALID_PRIO, 105, "Invalid priority", nil) - } - if len(*b.Title) == 0 { - return ginresp.SendAPIError(g, 400, apierr.NO_TITLE, 103, "No title specified", nil) - } - if b.UserMessageID != nil && len(*b.UserMessageID) > 64 { - return ginresp.SendAPIError(g, 400, apierr.USR_MSG_ID_TOO_LONG, -1, "MessageID too long (64 characters)", nil) - } - - user, err := h.database.GetUser(ctx, userID) - if err == sql.ErrNoRows { - return ginresp.SendAPIError(g, 400, apierr.USER_NOT_FOUND, -1, "User not found", nil) - } - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query user", err) - } - - channelName := user.DefaultChannel() - if b.Channel != nil { - channelName = h.app.NormalizeChannelName(*b.Channel) - } - - if len(*b.Title) > user.MaxTitleLength() { - return ginresp.SendAPIError(g, 400, apierr.TITLE_TOO_LONG, 103, fmt.Sprintf("Title too long (max %d characters)", user.MaxTitleLength()), nil) - } - if b.Content != nil && len(*b.Content) > user.MaxContentLength() { - return ginresp.SendAPIError(g, 400, apierr.CONTENT_TOO_LONG, 104, fmt.Sprintf("Content too long (%d characters; max := %d characters)", len(*b.Content), user.MaxContentLength()), nil) - } - if len(channelName) > user.MaxChannelNameLength() { - return ginresp.SendAPIError(g, 400, apierr.CONTENT_TOO_LONG, 106, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil) - } - - if b.UserMessageID != nil { - msg, err := h.database.GetMessageByUserMessageID(ctx, *b.UserMessageID) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query existing message", err) - } - if msg != nil { - return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, msg.FullJSON())) - } - } - - if user.QuotaRemainingToday() <= 0 { - return ginresp.SendAPIError(g, 403, apierr.QUOTA_REACHED, -1, fmt.Sprintf("Daily quota reached (%d)", user.QuotaPerDay()), nil) - } - - channel, err := h.app.GetOrCreateChannel(ctx, userID, channelName) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query/create channel", err) - } - - var sendTimestamp *time.Time = nil - if b.SendTimestamp != nil { - sendTimestamp = langext.Ptr(timeext.UnixFloatSeconds(*b.SendTimestamp)) - } - - priority := langext.Coalesce(b.Priority, 1) - - msg, err := h.database.CreateMessage(ctx, userID, channel, sendTimestamp, *b.Title, b.Content, priority, b.UserMessageID) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to create message in db", err) - } - - subscriptions, err := h.database.ListSubscriptionsByChannel(ctx, channel.ChannelID) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query subscriptions", err) - } - - err = h.database.IncUserMessageCounter(ctx, user) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to inc user msg-counter", err) - } - - err = h.database.IncChannelMessageCounter(ctx, channel) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to inc channel msg-counter", err) - } - - for _, sub := range subscriptions { - clients, err := h.database.ListClients(ctx, sub.SubscriberUserID) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query clients", err) - } - - if !sub.Confirmed { - continue - } - - for _, client := range clients { - - fcmDelivID, err := h.app.DeliverMessage(ctx, client, msg) - if err != nil { - _, err = h.database.CreateRetryDelivery(ctx, client, msg) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to create delivery", err) - } - } else { - _, err = h.database.CreateSuccessDelivery(ctx, client, msg, *fcmDelivID) - if err != nil { - return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to create delivery", err) - } - } - - } - } - - return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, msg.FullJSON())) -} diff --git a/server/api/handler/message.go b/server/api/handler/message.go index 8598325..b2db693 100644 --- a/server/api/handler/message.go +++ b/server/api/handler/message.go @@ -78,7 +78,7 @@ func (h MessageHandler) SendMessageCompat(g *gin.Context) ginresp.HTTPResponse { data := dataext.ObjectMerge(f, q) - return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, nil, nil, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp) + return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, nil, nil, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp, nil) } @@ -111,6 +111,7 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse { Priority *int `form:"priority"` UserMessageID *string `form:"msg_id"` SendTimestamp *float64 `form:"timestamp"` + SenderName *string `form:"sender_name"` } type body struct { UserID *models.UserID `json:"user_id"` @@ -122,6 +123,7 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse { Priority *int `json:"priority"` UserMessageID *string `json:"msg_id"` SendTimestamp *float64 `json:"timestamp"` + SenderName *string `json:"sender_name"` } type form struct { UserID *models.UserID `form:"user_id"` @@ -133,6 +135,7 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse { Priority *int `form:"priority"` UserMessageID *string `form:"msg_id"` SendTimestamp *float64 `form:"timestamp"` + SenderName *string `form:"sender_name"` } var b body @@ -146,11 +149,11 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse { data := dataext.ObjectMerge(dataext.ObjectMerge(b, f), q) - return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, data.Channel, data.ChanKey, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp) + return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, data.Channel, data.ChanKey, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp, data.SenderName) } -func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContext, UserID *models.UserID, UserKey *string, Channel *string, ChanKey *string, Title *string, Content *string, Priority *int, UserMessageID *string, SendTimestamp *float64) ginresp.HTTPResponse { +func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContext, UserID *models.UserID, UserKey *string, Channel *string, ChanKey *string, Title *string, Content *string, Priority *int, UserMessageID *string, SendTimestamp *float64, SenderName *string) ginresp.HTTPResponse { type response struct { Success bool `json:"success"` ErrorID apierr.APIError `json:"error"` @@ -189,9 +192,6 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex if len(*Title) == 0 { return ginresp.SendAPIError(g, 400, apierr.NO_TITLE, 103, "No title specified", nil) } - if UserMessageID != nil && len(*UserMessageID) > 64 { - return ginresp.SendAPIError(g, 400, apierr.USR_MSG_ID_TOO_LONG, -1, "MessageID too long (64 characters)", nil) - } user, err := h.database.GetUser(ctx, *UserID) if err == sql.ErrNoRows { @@ -215,6 +215,12 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex if len(channelName) > user.MaxChannelNameLength() { return ginresp.SendAPIError(g, 400, apierr.CONTENT_TOO_LONG, 106, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil) } + if SenderName != nil && len(*SenderName) > user.MaxSenderName() { + return ginresp.SendAPIError(g, 400, apierr.SENDERNAME_TOO_LONG, 107, fmt.Sprintf("SenderName too long (max %d characters)", user.MaxSenderName()), nil) + } + if UserMessageID != nil && len(*UserMessageID) > user.MaxUserMessageID() { + return ginresp.SendAPIError(g, 400, apierr.USR_MSG_ID_TOO_LONG, -1, fmt.Sprintf("MessageID too long (max %d characters)", user.MaxUserMessageID()), nil) + } if UserMessageID != nil { msg, err := h.database.GetMessageByUserMessageID(ctx, *UserMessageID) @@ -261,7 +267,9 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex priority := langext.Coalesce(Priority, 1) - msg, err := h.database.CreateMessage(ctx, *UserID, channel, sendTimestamp, *Title, Content, priority, UserMessageID) + clientIP := g.ClientIP() + + msg, err := h.database.CreateMessage(ctx, *UserID, channel, sendTimestamp, *Title, Content, priority, UserMessageID, clientIP, SenderName) if err != nil { return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to create message in db", err) } diff --git a/server/api/router.go b/server/api/router.go index 3fb3fbe..2453af9 100644 --- a/server/api/router.go +++ b/server/api/router.go @@ -135,8 +135,6 @@ func (r *Router) Init(e *gin.Engine) { apiv2.GET("/messages", ginresp.Wrap(r.apiHandler.ListMessages)) apiv2.GET("/messages/:mid", ginresp.Wrap(r.apiHandler.GetMessage)) apiv2.DELETE("/messages/:mid", ginresp.Wrap(r.apiHandler.DeleteMessage)) - - apiv2.POST("/messages", ginresp.Wrap(r.apiHandler.CreateMessage)) } // ================ Send API ================ diff --git a/server/db/messages.go b/server/db/messages.go index e32511e..62c1a64 100644 --- a/server/db/messages.go +++ b/server/db/messages.go @@ -49,7 +49,7 @@ func (db *Database) GetMessage(ctx TxContext, scnMessageID models.SCNMessageID) return msg, nil } -func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, channel models.Channel, timestampSend *time.Time, title string, content *string, priority int, userMsgId *string) (models.Message, error) { +func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, channel models.Channel, timestampSend *time.Time, title string, content *string, priority int, userMsgId *string, senderIP string, senderName *string) (models.Message, error) { tx, err := ctx.GetOrCreateTransaction(db) if err != nil { return models.Message{}, err @@ -57,7 +57,7 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, cha now := time.Now().UTC() - res, err := tx.ExecContext(ctx, "INSERT INTO messages (sender_user_id, owner_user_id, channel_name, channel_id, timestamp_real, timestamp_client, title, content, priority, usr_message_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + res, err := tx.ExecContext(ctx, "INSERT INTO messages (sender_user_id, owner_user_id, channel_name, channel_id, timestamp_real, timestamp_client, title, content, priority, usr_message_id, sender_ip, sender_name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", senderUserID, channel.OwnerUserID, channel.Name, @@ -67,7 +67,9 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, cha title, content, priority, - userMsgId) + userMsgId, + senderIP, + senderName) if err != nil { return models.Message{}, err } @@ -83,6 +85,8 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID models.UserID, cha OwnerUserID: channel.OwnerUserID, ChannelName: channel.Name, ChannelID: channel.ChannelID, + SenderIP: senderIP, + SenderName: senderName, TimestampReal: now, TimestampClient: timestampSend, Title: title, diff --git a/server/db/schema/schema_3.ddl b/server/db/schema/schema_3.ddl index cc40b3c..7f51c4f 100644 --- a/server/db/schema/schema_3.ddl +++ b/server/db/schema/schema_3.ddl @@ -81,6 +81,8 @@ CREATE TABLE messages owner_user_id INTEGER NOT NULL, channel_name TEXT NOT NULL, channel_id INTEGER NOT NULL, + sender_ip TEXT NOT NULL, + sender_name TEXT NULL, timestamp_real INTEGER NOT NULL, timestamp_client INTEGER NULL, @@ -90,8 +92,10 @@ CREATE TABLE messages priority INTEGER CHECK(priority IN (0, 1, 2)) NOT NULL, usr_message_id TEXT NULL ); -CREATE INDEX "idx_messages_channel" ON messages (owner_user_id, channel_name); -CREATE INDEX "idx_messages_idempotency" ON messages (owner_user_id, usr_message_id); +CREATE INDEX "idx_messages_channel" ON messages (owner_user_id, channel_name); +CREATE UNIQUE INDEX "idx_messages_idempotency" ON messages (owner_user_id, usr_message_id); +CREATE INDEX "idx_messages_senderip" ON messages (sender_ip); +CREATE INDEX "idx_messages_sendername" ON messages (sender_name); CREATE TABLE deliveries diff --git a/server/models/message.go b/server/models/message.go index 6f4a6ad..0abd207 100644 --- a/server/models/message.go +++ b/server/models/message.go @@ -18,6 +18,8 @@ type Message struct { OwnerUserID UserID ChannelName string ChannelID ChannelID + SenderName *string + SenderIP string TimestampReal time.Time TimestampClient *time.Time Title string @@ -33,6 +35,8 @@ func (m Message) FullJSON() MessageJSON { OwnerUserID: m.OwnerUserID, ChannelName: m.ChannelName, ChannelID: m.ChannelID, + SenderName: m.SenderName, + SenderIP: m.SenderIP, Timestamp: m.Timestamp().Format(time.RFC3339Nano), Title: m.Title, Content: m.Content, @@ -49,6 +53,8 @@ func (m Message) TrimmedJSON() MessageJSON { OwnerUserID: m.OwnerUserID, ChannelName: m.ChannelName, ChannelID: m.ChannelID, + SenderName: m.SenderName, + SenderIP: m.SenderIP, Timestamp: m.Timestamp().Format(time.RFC3339Nano), Title: m.Title, Content: m.TrimmedContent(), @@ -92,6 +98,8 @@ type MessageJSON struct { OwnerUserID UserID `json:"owner_user_id"` ChannelName string `json:"channel_name"` ChannelID ChannelID `json:"channel_id"` + SenderName *string `json:"sender_name"` + SenderIP string `json:"sender_ip"` Timestamp string `json:"timestamp"` Title string `json:"title"` Content *string `json:"body"` @@ -106,6 +114,8 @@ type MessageDB struct { OwnerUserID UserID `db:"owner_user_id"` ChannelName string `db:"channel_name"` ChannelID ChannelID `db:"channel_id"` + SenderName *string `db:"sender_name"` + SenderIP string `db:"sender_ip"` TimestampReal int64 `db:"timestamp_real"` TimestampClient *int64 `db:"timestamp_client"` Title string `db:"title"` @@ -121,6 +131,8 @@ func (m MessageDB) Model() Message { OwnerUserID: m.OwnerUserID, ChannelName: m.ChannelName, ChannelID: m.ChannelID, + SenderName: m.SenderName, + SenderIP: m.SenderIP, TimestampReal: time.UnixMilli(m.TimestampReal), TimestampClient: timeOptFromMilli(m.TimestampClient), Title: m.Title, diff --git a/server/models/user.go b/server/models/user.go index b332285..07d9d54 100644 --- a/server/models/user.go +++ b/server/models/user.go @@ -90,6 +90,14 @@ func (u User) MaxChannelNameLength() int { return 120 } +func (u User) MaxSenderName() int { + return 120 +} + +func (u User) MaxUserMessageID() int { + return 64 +} + type UserJSON struct { UserID UserID `json:"user_id"` Username *string `json:"username"` diff --git a/server/swagger/swagger.json b/server/swagger/swagger.json index 782062d..80c44ac 100644 --- a/server/swagger/swagger.json +++ b/server/swagger/swagger.json @@ -42,6 +42,11 @@ "name": "sendTimestamp", "in": "query" }, + { + "type": "string", + "name": "senderName", + "in": "query" + }, { "type": "string", "name": "title", @@ -95,6 +100,11 @@ "name": "priority", "in": "formData" }, + { + "type": "string", + "name": "sender_name", + "in": "formData" + }, { "type": "number", "name": "timestamp", @@ -394,6 +404,7 @@ }, { "type": "boolean", + "description": "TODO more filter (sender-name, channel, timestamps, prio, )", "name": "trimmed", "in": "query" } @@ -430,83 +441,6 @@ } } } - }, - "post": { - "description": "This is similar to the main route `POST -\u003e https://scn.blackfrestbytes.com/`\nBut this route can change in the future, for long-living scripts etc. it's better to use the normal POST route", - "tags": [ - "API-v2" - ], - "summary": "Create a new message", - "operationId": "api-messages-create", - "parameters": [ - { - "type": "string", - "name": "chan_key", - "in": "query" - }, - { - "type": "string", - "name": "channel", - "in": "query" - }, - { - "type": "string", - "name": "content", - "in": "query" - }, - { - "type": "string", - "name": "msg_id", - "in": "query" - }, - { - "type": "integer", - "name": "priority", - "in": "query" - }, - { - "type": "number", - "name": "timestamp", - "in": "query" - }, - { - "type": "string", - "name": "title", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/models.MessageJSON" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/ginresp.apiError" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/ginresp.apiError" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/ginresp.apiError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.apiError" - } - } - } } }, "/api/messages/{mid}": { @@ -2048,6 +1982,11 @@ "name": "sendTimestamp", "in": "query" }, + { + "type": "string", + "name": "senderName", + "in": "query" + }, { "type": "string", "name": "title", @@ -2101,6 +2040,11 @@ "name": "priority", "in": "formData" }, + { + "type": "string", + "name": "sender_name", + "in": "formData" + }, { "type": "number", "name": "timestamp", @@ -2603,6 +2547,9 @@ "priority": { "type": "integer" }, + "sender_name": { + "type": "string" + }, "timestamp": { "type": "number" }, @@ -2856,6 +2803,12 @@ "scn_message_id": { "type": "integer" }, + "sender_ip": { + "type": "string" + }, + "sender_name": { + "type": "string" + }, "sender_user_id": { "type": "integer" }, diff --git a/server/swagger/swagger.yaml b/server/swagger/swagger.yaml index 970758b..46797db 100644 --- a/server/swagger/swagger.yaml +++ b/server/swagger/swagger.yaml @@ -216,6 +216,8 @@ definitions: type: string priority: type: integer + sender_name: + type: string timestamp: type: number title: @@ -382,6 +384,10 @@ definitions: type: integer scn_message_id: type: integer + sender_ip: + type: string + sender_name: + type: string sender_user_id: type: integer timestamp: @@ -499,6 +505,9 @@ paths: - in: query name: sendTimestamp type: number + - in: query + name: senderName + type: string - in: query name: title type: string @@ -531,6 +540,9 @@ paths: - in: formData name: priority type: integer + - in: formData + name: sender_name + type: string - in: formData name: timestamp type: number @@ -735,7 +747,8 @@ paths: - in: query name: pageSize type: integer - - in: query + - description: TODO more filter (sender-name, channel, timestamps, prio, ) + in: query name: trimmed type: boolean responses: @@ -762,57 +775,6 @@ paths: summary: List all (subscribed) messages tags: - API-v2 - post: - description: |- - This is similar to the main route `POST -> https://scn.blackfrestbytes.com/` - But this route can change in the future, for long-living scripts etc. it's better to use the normal POST route - operationId: api-messages-create - parameters: - - in: query - name: chan_key - type: string - - in: query - name: channel - type: string - - in: query - name: content - type: string - - in: query - name: msg_id - type: string - - in: query - name: priority - type: integer - - in: query - name: timestamp - type: number - - in: query - name: title - type: string - responses: - "200": - description: OK - schema: - $ref: '#/definitions/models.MessageJSON' - "400": - description: Bad Request - schema: - $ref: '#/definitions/ginresp.apiError' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/ginresp.apiError' - "404": - description: Not Found - schema: - $ref: '#/definitions/ginresp.apiError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.apiError' - summary: Create a new message - tags: - - API-v2 /api/messages/{mid}: delete: description: The user must own the message and request the resource with the @@ -1854,6 +1816,9 @@ paths: - in: query name: sendTimestamp type: number + - in: query + name: senderName + type: string - in: query name: title type: string @@ -1886,6 +1851,9 @@ paths: - in: formData name: priority type: integer + - in: formData + name: sender_name + type: string - in: formData name: timestamp type: number diff --git a/server/website/api.html b/server/website/api.html index 0a25ae0..5f7c39a 100644 --- a/server/website/api.html +++ b/server/website/api.html @@ -30,6 +30,7 @@ curl \ --data "msg_id=$(uuidgen)" \ --data "timestamp=$(date +%s)" \ --data "channel={channel_name}" \ + --data "sender_name=$(hostname)" \ {{config|baseURL}}/
Most parameters are optional, you can send a message with only a title (default priority and channel will be used)
diff --git a/server/website/scn_send.dark.html b/server/website/scn_send.dark.html index 228b8fe..2200abb 100644 --- a/server/website/scn_send.dark.html +++ b/server/website/scn_send.dark.html @@ -41,8 +41,9 @@ usage() {content="" channel="" priority=1 -usr_msg_id=$(uuidgen) -sendtime=$(date +%s) +usr_msg_id="$(uuidgen)" +sendtime="$(date +%s)" +sender="$(hostname)" if [ ${#args[@]} -lt 1 ]; then echo "[ERROR]: no title supplied via parameter" 1>&2 @@ -64,7 +65,6 @@ usage() {title="${args[0]}" content="" -sendtime=$(date +%s) if [ ${#args[@]} -gt 1 ]; then content="${args[0]}" @@ -96,6 +96,7 @@ usage() {"priority=$priority" \ --data "msg_id=$usr_msg_id" \ --data "channel=$channel" \ + --data "sender_name=$sender" \ "https://scn.blackforestbytes.com/" ) if [ "$curlresp" == 200 ] ; then @@ -132,5 +133,6 @@ usage() {echo "Send failed (response code $curlresp) ... try again in 5s" 1>&2 sleep 5 done +diff --git a/server/website/scn_send.light.html b/server/website/scn_send.light.html index 041ec63..b8a8fa0 100644 --- a/server/website/scn_send.light.html +++ b/server/website/scn_send.light.html @@ -41,8 +41,9 @@ title=$1 content="" channel="" priority=1 -usr_msg_id=$(uuidgen) -sendtime=$(date +%s) +usr_msg_id="$(uuidgen)" +sendtime="$(date +%s)" +sender="$(hostname)" if [ ${#args[@]} -lt 1 ]; then echo "[ERROR]: no title supplied via parameter" 1>&2 @@ -64,7 +65,6 @@ sendtime=$(date +%s"${args[0]}" content="" -sendtime=$(date +%s) if [ ${#args[@]} -gt 1 ]; then content="${args[0]}" @@ -96,6 +96,7 @@ sendtime=$(date +%s"priority=$priority" \ --data "msg_id=$usr_msg_id" \ --data "channel=$channel" \ + --data "sender_name=$sender" \ "https://scn.blackforestbytes.com/" ) if [ "$curlresp" == 200 ] ; then