From bc4205bff5381f9cd1fadcc8b87973a05a582b1f Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Fri, 20 Jul 2018 12:48:54 +0200 Subject: [PATCH] Stabilised messages endpoints, connected with message service --- sam/docs/README.md | 27 ++++++++--- sam/docs/src/spec.json | 33 ++++++++----- sam/docs/src/spec/channel.json | 6 +++ sam/docs/src/spec/message.json | 38 ++++++++++----- sam/repository/error.go | 4 ++ sam/repository/message.go | 23 +++++++-- sam/rest/message.go | 74 +++++++++++++++++++++++------ sam/rest/router.go | 7 +-- sam/rest/server/channel_requests.go | 5 +- sam/rest/server/message.go | 6 ++- sam/rest/server/message_handlers.go | 10 ++-- sam/rest/server/message_requests.go | 65 ++++++++++++++++++------- sam/service/mesage.go | 54 +++++++++++++++++++-- sam/types/message_filter.go | 5 +- 14 files changed, 276 insertions(+), 81 deletions(-) diff --git a/sam/docs/README.md b/sam/docs/README.md index ead3ed6db..80acb36e0 100644 --- a/sam/docs/README.md +++ b/sam/docs/README.md @@ -231,6 +231,7 @@ A channel is a representation of a sequence of messages. It has meta data like c | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | | query | string | GET | Search query | N/A | NO | +| sinceMessageId | uint64 | GET | | N/A | NO | ## Create new channel @@ -330,7 +331,21 @@ The following event types may be sent with a message event: | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | -| contents | string | POST | Message contents (markdown) | N/A | YES | +| message | string | POST | Message contents (markdown) | N/A | YES | + +## All messages (channel history) + +#### Method + +| URI | Protocol | Method | Authentication | +| --- | -------- | ------ | -------------- | +| `/channels/{channelId}/messages/` | HTTP/S | GET | Client ID, Session ID | + +#### Request parameters + +| Parameter | Type | Method | Description | Default | Required? | +| --------- | ---- | ------ | ----------- | ------- | --------- | +| lastMessageId | uint64 | GET | | N/A | NO | ## Edit existing message @@ -345,7 +360,7 @@ The following event types may be sent with a message event: | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | | messageId | uint64 | PATH | Message ID | N/A | YES | -| contents | string | POST | Message contents (markdown) | N/A | YES | +| message | string | POST | Message contents (markdown) | N/A | YES | ## Delete existing message @@ -451,14 +466,14 @@ The following event types may be sent with a message event: | URI | Protocol | Method | Authentication | | --- | -------- | ------ | -------------- | -| `/channels/{channelId}/messages/{messageId}/react` | HTTP/S | POST | Client ID, Session ID | +| `/channels/{channelId}/messages/{messageId}/reaction/{reaction}` | HTTP/S | PUT | Client ID, Session ID | #### Request parameters | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | | messageId | uint64 | PATH | Message ID | N/A | YES | -| reaction | string | POST | Reaction | N/A | YES | +| reaction | string | PATH | Reaction | N/A | YES | ## Delete reaction from a message @@ -466,14 +481,14 @@ The following event types may be sent with a message event: | URI | Protocol | Method | Authentication | | --- | -------- | ------ | -------------- | -| `/channels/{channelId}/messages/{messageId}/react/{reactionId}` | HTTP/S | DELETE | Client ID, Session ID | +| `/channels/{channelId}/messages/{messageId}/react/{reaction}` | HTTP/S | DELETE | Client ID, Session ID | #### Request parameters | Parameter | Type | Method | Description | Default | Required? | | --------- | ---- | ------ | ----------- | ------- | --------- | | messageId | uint64 | PATH | Message ID | N/A | YES | -| reactionId | uint64 | PATH | Reaction ID | N/A | YES | +| reaction | string | PATH | Reaction | N/A | YES | diff --git a/sam/docs/src/spec.json b/sam/docs/src/spec.json index 92ea78bfa..96cf83276 100644 --- a/sam/docs/src/spec.json +++ b/sam/docs/src/spec.json @@ -246,7 +246,7 @@ "path": "/", "parameters": { "GET": [ - { "type": "string", "name": "query", "required": false, "title": "Search query" } + { "type": "string", "name": "query", "required": false, "title": "Search query" }, ] } }, @@ -363,7 +363,18 @@ "title": "Post new message to the channel", "parameters": { "post": [ - { "type": "string", "name": "contents", "required": true, "title": "Message contents (markdown)" } + { "type": "string", "name": "message", "required": true, "title": "Message contents (markdown)" } + ] + } + }, + { + "name": "history", + "path": "/", + "method": "GET", + "title": "All messages (channel history)", + "parameters": { + "get": [ + { "name": "lastMessageId", "type": "uint64", "required": false, "title": "" } ] } }, @@ -377,7 +388,7 @@ { "name": "messageId", "type": "uint64", "required": true, "title": "Message ID" } ], "post": [ - { "type": "string", "name": "contents", "required": true, "title": "Message contents (markdown)" } + { "type": "string", "name": "message", "required": true, "title": "Message contents (markdown)" } ] } }, @@ -458,7 +469,7 @@ } }, { - "name": "deflag", + "name": "unflag", "path": "/{messageId}/flag", "method": "DELETE", "title": "Remove flag from message (private bookmark)", @@ -470,27 +481,25 @@ }, { "name": "react", - "path": "/{messageId}/react", - "method": "POST", + "path": "/{messageId}/reaction/{reaction}", + "method": "PUT", "title": "React to a message", "parameters": { "path": [ - { "name": "messageId", "type": "uint64", "required": true, "title": "Message ID" } - ], - "post": [ - { "type": "string", "name": "reaction", "required": true, "title": "Reaction" } + { "name": "messageId", "type": "uint64", "required": true, "title": "Message ID" }, + { "name": "reaction", "type": "string", "required": true, "title": "Reaction" } ] } }, { "name": "unreact", - "path": "/{messageId}/react/{reactionId}", + "path": "/{messageId}/react/{reaction}", "method": "DELETE", "title": "Delete reaction from a message", "parameters": { "path": [ { "name": "messageId", "type": "uint64", "required": true, "title": "Message ID" }, - { "name": "reactionId", "type": "uint64", "required": true, "title": "Reaction ID" } + { "name": "reaction", "type": "string", "required": true, "title": "Reaction" } ] } } diff --git a/sam/docs/src/spec/channel.json b/sam/docs/src/spec/channel.json index 3c553c6aa..9f6a262a7 100644 --- a/sam/docs/src/spec/channel.json +++ b/sam/docs/src/spec/channel.json @@ -70,6 +70,12 @@ "required": false, "title": "Search query", "type": "string" + }, + { + "name": "sinceMessageId", + "required": false, + "title": "", + "type": "uint64" } ] } diff --git a/sam/docs/src/spec/message.json b/sam/docs/src/spec/message.json index 3460635e2..de915ed1a 100644 --- a/sam/docs/src/spec/message.json +++ b/sam/docs/src/spec/message.json @@ -152,7 +152,7 @@ "Parameters": { "post": [ { - "name": "contents", + "name": "message", "required": true, "title": "Message contents (markdown)", "type": "string" @@ -160,6 +160,22 @@ ] } }, + { + "Name": "history", + "Method": "GET", + "Title": "All messages (channel history)", + "Path": "/", + "Parameters": { + "get": [ + { + "name": "lastMessageId", + "required": false, + "title": "", + "type": "uint64" + } + ] + } + }, { "Name": "edit", "Method": "PUT", @@ -176,7 +192,7 @@ ], "post": [ { - "name": "contents", + "name": "message", "required": true, "title": "Message contents (markdown)", "type": "string" @@ -284,7 +300,7 @@ } }, { - "Name": "deflag", + "Name": "unflag", "Method": "DELETE", "Title": "Remove flag from message (private bookmark)", "Path": "/{messageId}/flag", @@ -301,9 +317,9 @@ }, { "Name": "react", - "Method": "POST", + "Method": "PUT", "Title": "React to a message", - "Path": "/{messageId}/react", + "Path": "/{messageId}/reaction/{reaction}", "Parameters": { "path": [ { @@ -311,9 +327,7 @@ "required": true, "title": "Message ID", "type": "uint64" - } - ], - "post": [ + }, { "name": "reaction", "required": true, @@ -327,7 +341,7 @@ "Name": "unreact", "Method": "DELETE", "Title": "Delete reaction from a message", - "Path": "/{messageId}/react/{reactionId}", + "Path": "/{messageId}/react/{reaction}", "Parameters": { "path": [ { @@ -337,10 +351,10 @@ "type": "uint64" }, { - "name": "reactionId", + "name": "reaction", "required": true, - "title": "Reaction ID", - "type": "uint64" + "title": "Reaction", + "type": "string" } ] } diff --git a/sam/repository/error.go b/sam/repository/error.go index bb9751074..cd9a917d4 100644 --- a/sam/repository/error.go +++ b/sam/repository/error.go @@ -10,5 +10,9 @@ const ( ) func (e repositoryError) Error() string { + return e.String() +} + +func (e repositoryError) String() string { return "crust.sam.repository." + string(e) } diff --git a/sam/repository/message.go b/sam/repository/message.go index 2b3a6b4c9..50597de48 100644 --- a/sam/repository/message.go +++ b/sam/repository/message.go @@ -3,6 +3,7 @@ package repository import ( "context" "github.com/crusttech/crust/sam/types" + "github.com/pkg/errors" "github.com/titpetric/factory" ) @@ -23,9 +24,11 @@ func Message() message { func (r message) FindById(ctx context.Context, id uint64) (*types.Message, error) { db := factory.Database.MustGet() + sql := "SELECT id, COALESCE(type,'') AS type, message, rel_user, rel_channel, COALESCE(reply_to, 0) AS reply_to FROM messages WHERE id = ? AND " + sqlMessageScope + mod := &types.Message{} - if err := db.GetContext(ctx, mod, "SELECT * FROM messages WHERE id = ? AND "+sqlMessageScope, id); err != nil { - return nil, ErrDatabaseError + if err := db.GetContext(ctx, mod, sql, id); err != nil { + return nil, errors.Wrap(err, ErrDatabaseError.String()) } else if mod.ID == 0 { return nil, ErrMessageNotFound } else { @@ -37,7 +40,7 @@ func (r message) Find(ctx context.Context, filter *types.MessageFilter) ([]*type db := factory.Database.MustGet() var params = make([]interface{}, 0) - sql := "SELECT * FROM messages WHERE " + sqlMessageScope + sql := "SELECT id, COALESCE(type,'') AS type, message, rel_user, rel_channel, COALESCE(reply_to, 0) AS reply_to FROM messages WHERE " + sqlMessageScope if filter != nil { if filter.Query != "" { @@ -46,11 +49,21 @@ func (r message) Find(ctx context.Context, filter *types.MessageFilter) ([]*type } } - sql += " ORDER BY name ASC" + if filter.ChannelId > 0 { + sql += " AND rel_channel = ? " + params = append(params, filter.ChannelId) + } + + if filter.LastMessageId > 0 { + sql += " AND id > ? " + params = append(params, filter.LastMessageId) + } + + sql += " ORDER BY id ASC" rval := make([]*types.Message, 0) if err := db.SelectContext(ctx, &rval, sql, params...); err != nil { - return nil, ErrDatabaseError + return nil, errors.Wrap(err, ErrDatabaseError.String()) } else { return rval, nil } diff --git a/sam/rest/message.go b/sam/rest/message.go index de5d802e6..bf6960e12 100644 --- a/sam/rest/message.go +++ b/sam/rest/message.go @@ -3,57 +3,103 @@ package rest import ( "context" "github.com/crusttech/crust/sam/rest/server" + "github.com/crusttech/crust/sam/service" + "github.com/crusttech/crust/sam/types" + "github.com/davecgh/go-spew/spew" "github.com/pkg/errors" ) var _ = errors.Wrap -type Message struct{} +type ( + Message struct { + service messageService + } + + messageService interface { + Find(context.Context, *types.MessageFilter) ([]*types.Message, error) + + Create(context.Context, *types.Message) (*types.Message, error) + Update(context.Context, *types.Message) (*types.Message, error) + + React(context.Context, uint64, string) error + Unreact(context.Context, uint64, string) error + + Pin(context.Context, uint64) error + Unpin(context.Context, uint64) error + + Flag(context.Context, uint64) error + Unflag(context.Context, uint64) error + + Attach(context.Context) (*types.Attachment, error) + Detach(context.Context, uint64) error + + deleter + } +) func (Message) New() *Message { - return &Message{} + return &Message{ + service: service.Message(), + } } func (ctrl *Message) Create(ctx context.Context, r *server.MessageCreateRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.create") + spew.Dump(r) + return ctrl.service.Create(ctx, (&types.Message{}). + SetChannelId(r.ChannelId). + SetMessage(r.Message)) +} + +func (ctrl *Message) History(ctx context.Context, r *server.MessageHistoryRequest) (interface{}, error) { + return ctrl.service.Find(ctx, &types.MessageFilter{ + ChannelId: r.ChannelId, + LastMessageId: r.LastMessageId, + }) } func (ctrl *Message) Edit(ctx context.Context, r *server.MessageEditRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.edit") + return ctrl.service.Update(ctx, (&types.Message{}). + SetID(r.MessageId). + SetChannelId(r.ChannelId). + SetMessage(r.Message)) } func (ctrl *Message) Delete(ctx context.Context, r *server.MessageDeleteRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.delete") + return nil, ctrl.service.Delete(ctx, r.MessageId) } func (ctrl *Message) Attach(ctx context.Context, r *server.MessageAttachRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.attach") + return ctrl.service.Attach(ctx) } func (ctrl *Message) Search(ctx context.Context, r *server.MessageSearchRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.search") + return ctrl.service.Find(ctx, &types.MessageFilter{ + ChannelId: r.ChannelId, + Query: r.Query, + }) } func (ctrl *Message) Pin(ctx context.Context, r *server.MessagePinRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.pin") + return nil, ctrl.service.Pin(ctx, r.MessageId) } func (ctrl *Message) Unpin(ctx context.Context, r *server.MessageUnpinRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.unpin") + return nil, ctrl.service.Unpin(ctx, r.MessageId) } func (ctrl *Message) Flag(ctx context.Context, r *server.MessageFlagRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.flag") + return nil, ctrl.service.Flag(ctx, r.MessageId) } -func (ctrl *Message) Deflag(ctx context.Context, r *server.MessageDeflagRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.deflag") +func (ctrl *Message) Unflag(ctx context.Context, r *server.MessageUnflagRequest) (interface{}, error) { + return nil, ctrl.service.Unflag(ctx, r.MessageId) } func (ctrl *Message) React(ctx context.Context, r *server.MessageReactRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.react") + return nil, ctrl.service.React(ctx, r.MessageId, r.Reaction) } func (ctrl *Message) Unreact(ctx context.Context, r *server.MessageUnreactRequest) (interface{}, error) { - return nil, errors.New("Not implemented: Message.unreact") + return nil, ctrl.service.Unreact(ctx, r.MessageId, r.Reaction) } diff --git a/sam/rest/router.go b/sam/rest/router.go index 59c4f03c8..aab52956f 100644 --- a/sam/rest/router.go +++ b/sam/rest/router.go @@ -48,6 +48,7 @@ func MountRoutes(r chi.Router) { r.Use(message.Message.Authenticator()) r.Route("/channels/{channelId}/messages", func(r chi.Router) { r.Post("/", message.Create) + r.Get("/", message.History) r.Put("/{messageId}", message.Edit) r.Delete("/{messageId}", message.Delete) r.Put("/{messageId}/attach", message.Attach) @@ -55,9 +56,9 @@ func MountRoutes(r chi.Router) { r.Post("/{messageId}/pin", message.Pin) r.Delete("/{messageId}/pin", message.Unpin) r.Post("/{messageId}/flag", message.Flag) - r.Delete("/{messageId}/flag", message.Deflag) - r.Post("/{messageId}/react", message.React) - r.Delete("/{messageId}/react/{reactionId}", message.Unreact) + r.Delete("/{messageId}/flag", message.Unflag) + r.Put("/{messageId}/reaction/{reaction}", message.React) + r.Delete("/{messageId}/react/{reaction}", message.Unreact) }) }) r.Group(func(r chi.Router) { diff --git a/sam/rest/server/channel_requests.go b/sam/rest/server/channel_requests.go index 3987be383..0939d4fc2 100644 --- a/sam/rest/server/channel_requests.go +++ b/sam/rest/server/channel_requests.go @@ -24,7 +24,8 @@ var _ = chi.URLParam // Channel list request parameters type ChannelListRequest struct { - Query string + Query string + SinceMessageId uint64 } func (ChannelListRequest) new() *ChannelListRequest { @@ -45,6 +46,8 @@ func (c *ChannelListRequest) Fill(r *http.Request) error { } c.Query = get["query"] + + c.SinceMessageId = parseUInt64(get["sinceMessageId"]) return nil } diff --git a/sam/rest/server/message.go b/sam/rest/server/message.go index afc1e1535..d8902a1b0 100644 --- a/sam/rest/server/message.go +++ b/sam/rest/server/message.go @@ -28,6 +28,7 @@ type MessageHandlers struct { // Internal API interface type MessageAPI interface { Create(context.Context, *MessageCreateRequest) (interface{}, error) + History(context.Context, *MessageHistoryRequest) (interface{}, error) Edit(context.Context, *MessageEditRequest) (interface{}, error) Delete(context.Context, *MessageDeleteRequest) (interface{}, error) Attach(context.Context, *MessageAttachRequest) (interface{}, error) @@ -35,7 +36,7 @@ type MessageAPI interface { Pin(context.Context, *MessagePinRequest) (interface{}, error) Unpin(context.Context, *MessageUnpinRequest) (interface{}, error) Flag(context.Context, *MessageFlagRequest) (interface{}, error) - Deflag(context.Context, *MessageDeflagRequest) (interface{}, error) + Unflag(context.Context, *MessageUnflagRequest) (interface{}, error) React(context.Context, *MessageReactRequest) (interface{}, error) Unreact(context.Context, *MessageUnreactRequest) (interface{}, error) @@ -46,6 +47,7 @@ type MessageAPI interface { // HTTP API interface type MessageHandlersAPI interface { Create(http.ResponseWriter, *http.Request) + History(http.ResponseWriter, *http.Request) Edit(http.ResponseWriter, *http.Request) Delete(http.ResponseWriter, *http.Request) Attach(http.ResponseWriter, *http.Request) @@ -53,7 +55,7 @@ type MessageHandlersAPI interface { Pin(http.ResponseWriter, *http.Request) Unpin(http.ResponseWriter, *http.Request) Flag(http.ResponseWriter, *http.Request) - Deflag(http.ResponseWriter, *http.Request) + Unflag(http.ResponseWriter, *http.Request) React(http.ResponseWriter, *http.Request) Unreact(http.ResponseWriter, *http.Request) } diff --git a/sam/rest/server/message_handlers.go b/sam/rest/server/message_handlers.go index db4031b95..aebe2565c 100644 --- a/sam/rest/server/message_handlers.go +++ b/sam/rest/server/message_handlers.go @@ -25,6 +25,10 @@ func (mh *MessageHandlers) Create(w http.ResponseWriter, r *http.Request) { params := MessageCreateRequest{}.new() resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.Create(r.Context(), params) }) } +func (mh *MessageHandlers) History(w http.ResponseWriter, r *http.Request) { + params := MessageHistoryRequest{}.new() + resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.History(r.Context(), params) }) +} func (mh *MessageHandlers) Edit(w http.ResponseWriter, r *http.Request) { params := MessageEditRequest{}.new() resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.Edit(r.Context(), params) }) @@ -53,9 +57,9 @@ func (mh *MessageHandlers) Flag(w http.ResponseWriter, r *http.Request) { params := MessageFlagRequest{}.new() resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.Flag(r.Context(), params) }) } -func (mh *MessageHandlers) Deflag(w http.ResponseWriter, r *http.Request) { - params := MessageDeflagRequest{}.new() - resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.Deflag(r.Context(), params) }) +func (mh *MessageHandlers) Unflag(w http.ResponseWriter, r *http.Request) { + params := MessageUnflagRequest{}.new() + resputil.JSON(w, params.Fill(r), func() (interface{}, error) { return mh.Message.Unflag(r.Context(), params) }) } func (mh *MessageHandlers) React(w http.ResponseWriter, r *http.Request) { params := MessageReactRequest{}.new() diff --git a/sam/rest/server/message_requests.go b/sam/rest/server/message_requests.go index 825b6c344..ed29feb34 100644 --- a/sam/rest/server/message_requests.go +++ b/sam/rest/server/message_requests.go @@ -24,7 +24,7 @@ var _ = chi.URLParam // Message create request parameters type MessageCreateRequest struct { - Contents string + Message string ChannelId uint64 } @@ -45,7 +45,7 @@ func (m *MessageCreateRequest) Fill(r *http.Request) error { post[name] = string(param[0]) } - m.Contents = post["contents"] + m.Message = post["message"] m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) return nil @@ -53,11 +53,42 @@ func (m *MessageCreateRequest) Fill(r *http.Request) error { var _ RequestFiller = MessageCreateRequest{}.new() +// Message history request parameters +type MessageHistoryRequest struct { + LastMessageId uint64 + ChannelId uint64 +} + +func (MessageHistoryRequest) new() *MessageHistoryRequest { + return &MessageHistoryRequest{} +} + +func (m *MessageHistoryRequest) Fill(r *http.Request) error { + r.ParseForm() + get := map[string]string{} + post := map[string]string{} + urlQuery := r.URL.Query() + for name, param := range urlQuery { + get[name] = string(param[0]) + } + postVars := r.Form + for name, param := range postVars { + post[name] = string(param[0]) + } + + m.LastMessageId = parseUInt64(get["lastMessageId"]) + + m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) + return nil +} + +var _ RequestFiller = MessageHistoryRequest{}.new() + // Message edit request parameters type MessageEditRequest struct { MessageId uint64 ChannelId uint64 - Contents string + Message string } func (MessageEditRequest) new() *MessageEditRequest { @@ -81,7 +112,7 @@ func (m *MessageEditRequest) Fill(r *http.Request) error { m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) - m.Contents = post["contents"] + m.Message = post["message"] return nil } @@ -273,17 +304,17 @@ func (m *MessageFlagRequest) Fill(r *http.Request) error { var _ RequestFiller = MessageFlagRequest{}.new() -// Message deflag request parameters -type MessageDeflagRequest struct { +// Message unflag request parameters +type MessageUnflagRequest struct { MessageId uint64 ChannelId uint64 } -func (MessageDeflagRequest) new() *MessageDeflagRequest { - return &MessageDeflagRequest{} +func (MessageUnflagRequest) new() *MessageUnflagRequest { + return &MessageUnflagRequest{} } -func (m *MessageDeflagRequest) Fill(r *http.Request) error { +func (m *MessageUnflagRequest) Fill(r *http.Request) error { r.ParseForm() get := map[string]string{} post := map[string]string{} @@ -302,13 +333,13 @@ func (m *MessageDeflagRequest) Fill(r *http.Request) error { return nil } -var _ RequestFiller = MessageDeflagRequest{}.new() +var _ RequestFiller = MessageUnflagRequest{}.new() // Message react request parameters type MessageReactRequest struct { MessageId uint64 - ChannelId uint64 Reaction string + ChannelId uint64 } func (MessageReactRequest) new() *MessageReactRequest { @@ -330,9 +361,9 @@ func (m *MessageReactRequest) Fill(r *http.Request) error { m.MessageId = parseUInt64(chi.URLParam(r, "messageId")) - m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) + m.Reaction = chi.URLParam(r, "reaction") - m.Reaction = post["reaction"] + m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) return nil } @@ -340,9 +371,9 @@ var _ RequestFiller = MessageReactRequest{}.new() // Message unreact request parameters type MessageUnreactRequest struct { - MessageId uint64 - ReactionId uint64 - ChannelId uint64 + MessageId uint64 + Reaction string + ChannelId uint64 } func (MessageUnreactRequest) new() *MessageUnreactRequest { @@ -364,7 +395,7 @@ func (m *MessageUnreactRequest) Fill(r *http.Request) error { m.MessageId = parseUInt64(chi.URLParam(r, "messageId")) - m.ReactionId = parseUInt64(chi.URLParam(r, "reactionId")) + m.Reaction = chi.URLParam(r, "reaction") m.ChannelId = parseUInt64(chi.URLParam(r, "channelId")) return nil diff --git a/sam/service/mesage.go b/sam/service/mesage.go index 409e0b08f..a7706e991 100644 --- a/sam/service/mesage.go +++ b/sam/service/mesage.go @@ -53,6 +53,7 @@ func (svc message) Find(ctx context.Context, filter *types.MessageFilter) ([]*ty // @todo verify if current user can access & write to this channel _ = currentUserId + _ = filter.ChannelId return svc.repository.message.Find(ctx, filter) } @@ -95,7 +96,7 @@ func (svc message) Delete(ctx context.Context, id uint64) error { return svc.repository.message.Delete(ctx, id) } -func (svc message) React(ctx context.Context, messageId uint64, reaction string) (*types.Reaction, error) { +func (svc message) React(ctx context.Context, messageId uint64, reaction string) error { // @todo get user from context var currentUserId uint64 = 0 @@ -111,10 +112,14 @@ func (svc message) React(ctx context.Context, messageId uint64, reaction string) Reaction: reaction, } - return svc.repository.reaction.Create(ctx, r) + if _, err := svc.repository.reaction.Create(ctx, r); err != nil { + return err + } + + return nil } -func (svc message) Unreact(ctx context.Context, reactionId uint64) error { +func (svc message) Unreact(ctx context.Context, messageId uint64, reaction string) error { // @todo get user from context var currentUserId uint64 = 0 @@ -122,8 +127,49 @@ func (svc message) Unreact(ctx context.Context, reactionId uint64) error { _ = currentUserId // @todo load reaction and verify ownership + var r *types.Reaction - return svc.repository.reaction.Delete(ctx, reactionId) + return svc.repository.reaction.Delete(ctx, r.ID) +} + +func (svc message) Pin(ctx context.Context, messageId uint64) error { + // @todo get user from context + var currentUserId uint64 = 0 + + // @todo verify if current user can access & write to this channel + _ = currentUserId + + return nil +} + +func (svc message) Unpin(ctx context.Context, messageId uint64) error { + // @todo get user from context + var currentUserId uint64 = 0 + + // @todo verify if current user can access & write to this channel + _ = currentUserId + + return nil +} + +func (svc message) Flag(ctx context.Context, messageId uint64) error { + // @todo get user from context + var currentUserId uint64 = 0 + + // @todo verify if current user can access & write to this channel + _ = currentUserId + + return nil +} + +func (svc message) Unflag(ctx context.Context, messageId uint64) error { + // @todo get user from context + var currentUserId uint64 = 0 + + // @todo verify if current user can access & write to this channel + _ = currentUserId + + return nil } func (svc message) Attach(ctx context.Context) (*types.Attachment, error) { diff --git a/sam/types/message_filter.go b/sam/types/message_filter.go index 3b40ce19b..e6fe225d2 100644 --- a/sam/types/message_filter.go +++ b/sam/types/message_filter.go @@ -2,7 +2,8 @@ package types type ( MessageFilter struct { - Query string - ChannelId string + Query string + ChannelId uint64 + LastMessageId uint64 } )