Skip to content

Commit 6602902

Browse files
committed
Add the ability to delete threads and all messages NdoleStudio#322
1 parent 8c030b6 commit 6602902

17 files changed

Lines changed: 449 additions & 19 deletions

api/docs/docs.go

Lines changed: 68 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/docs/swagger.json

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@
680680
"description": "Get list of contacts which a phone number has communicated with (threads). It will be sorted by timestamp in descending order.",
681681
"consumes": ["application/json"],
682682
"produces": ["application/json"],
683-
"tags": ["Channel Threads"],
683+
"tags": ["MessageThreads"],
684684
"summary": "Get message threads for a phone number",
685685
"parameters": [
686686
{
@@ -757,7 +757,7 @@
757757
"description": "Updates the details of a message thread",
758758
"consumes": ["application/json"],
759759
"produces": ["application/json"],
760-
"tags": ["Channel Threads"],
760+
"tags": ["MessageThreads"],
761761
"summary": "Update a message thread",
762762
"parameters": [
763763
{
@@ -810,6 +810,66 @@
810810
}
811811
}
812812
}
813+
},
814+
"delete": {
815+
"security": [
816+
{
817+
"ApiKeyAuth": []
818+
}
819+
],
820+
"description": "Delete a message thread from the database and also deletes all the messages in the thread.",
821+
"consumes": ["application/json"],
822+
"produces": ["application/json"],
823+
"tags": ["MessageThreads"],
824+
"summary": "Delete a message thread from the database.",
825+
"parameters": [
826+
{
827+
"type": "string",
828+
"default": "32343a19-da5e-4b1b-a767-3298a73703ca",
829+
"description": "ID of the message thread",
830+
"name": "messageID",
831+
"in": "path",
832+
"required": true
833+
}
834+
],
835+
"responses": {
836+
"204": {
837+
"description": "No Content",
838+
"schema": {
839+
"$ref": "#/definitions/responses.NoContent"
840+
}
841+
},
842+
"400": {
843+
"description": "Bad Request",
844+
"schema": {
845+
"$ref": "#/definitions/responses.BadRequest"
846+
}
847+
},
848+
"401": {
849+
"description": "Unauthorized",
850+
"schema": {
851+
"$ref": "#/definitions/responses.Unauthorized"
852+
}
853+
},
854+
"404": {
855+
"description": "Not Found",
856+
"schema": {
857+
"$ref": "#/definitions/responses.NotFound"
858+
}
859+
},
860+
"422": {
861+
"description": "Unprocessable Entity",
862+
"schema": {
863+
"$ref": "#/definitions/responses.UnprocessableEntity"
864+
}
865+
},
866+
"500": {
867+
"description": "Internal Server Error",
868+
"schema": {
869+
"$ref": "#/definitions/responses.InternalServerError"
870+
}
871+
}
872+
}
813873
}
814874
},
815875
"/messages": {

api/docs/swagger.yaml

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,8 +1594,53 @@ paths:
15941594
- ApiKeyAuth: []
15951595
summary: Get message threads for a phone number
15961596
tags:
1597-
- Channel Threads
1597+
- MessageThreads
15981598
/message-threads/{messageThreadID}:
1599+
delete:
1600+
consumes:
1601+
- application/json
1602+
description:
1603+
Delete a message thread from the database and also deletes all
1604+
the messages in the thread.
1605+
parameters:
1606+
- default: 32343a19-da5e-4b1b-a767-3298a73703ca
1607+
description: ID of the message thread
1608+
in: path
1609+
name: messageID
1610+
required: true
1611+
type: string
1612+
produces:
1613+
- application/json
1614+
responses:
1615+
"204":
1616+
description: No Content
1617+
schema:
1618+
$ref: "#/definitions/responses.NoContent"
1619+
"400":
1620+
description: Bad Request
1621+
schema:
1622+
$ref: "#/definitions/responses.BadRequest"
1623+
"401":
1624+
description: Unauthorized
1625+
schema:
1626+
$ref: "#/definitions/responses.Unauthorized"
1627+
"404":
1628+
description: Not Found
1629+
schema:
1630+
$ref: "#/definitions/responses.NotFound"
1631+
"422":
1632+
description: Unprocessable Entity
1633+
schema:
1634+
$ref: "#/definitions/responses.UnprocessableEntity"
1635+
"500":
1636+
description: Internal Server Error
1637+
schema:
1638+
$ref: "#/definitions/responses.InternalServerError"
1639+
security:
1640+
- ApiKeyAuth: []
1641+
summary: Delete a message thread from the database.
1642+
tags:
1643+
- MessageThreads
15991644
put:
16001645
consumes:
16011646
- application/json
@@ -1640,7 +1685,7 @@ paths:
16401685
- ApiKeyAuth: []
16411686
summary: Update a message thread
16421687
tags:
1643-
- Channel Threads
1688+
- MessageThreads
16441689
/messages:
16451690
get:
16461691
consumes:

api/pkg/di/container.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,7 @@ func (container *Container) MessageThreadService() (service *services.MessageThr
891891
container.Logger(),
892892
container.Tracer(),
893893
container.MessageThreadRepository(),
894+
container.EventDispatcher(),
894895
)
895896
}
896897

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package events
2+
3+
import (
4+
"time"
5+
6+
"github.com/NdoleStudio/httpsms/pkg/entities"
7+
8+
"github.com/google/uuid"
9+
)
10+
11+
// MessageThreadAPIDeleted is emitted when a new message is deleted
12+
const MessageThreadAPIDeleted = "message-thread.api.deleted"
13+
14+
// MessageThreadAPIDeletedPayload is the payload of the MessageThreadAPIDeleted event
15+
type MessageThreadAPIDeletedPayload struct {
16+
MessageThreadID uuid.UUID `json:"message_thread_id"`
17+
UserID entities.UserID `json:"user_id"`
18+
Owner string `json:"owner"`
19+
Contact string `json:"contact"`
20+
IsArchived bool `json:"is_archived"`
21+
Color string `json:"color"`
22+
Status entities.MessageStatus `json:"status"`
23+
Timestamp time.Time `json:"timestamp"`
24+
}

api/pkg/handlers/message_thread_handler.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package handlers
33
import (
44
"fmt"
55

6+
"github.com/NdoleStudio/httpsms/pkg/repositories"
7+
"github.com/google/uuid"
8+
69
"github.com/NdoleStudio/httpsms/pkg/requests"
710
"github.com/NdoleStudio/httpsms/pkg/services"
811
"github.com/NdoleStudio/httpsms/pkg/telemetry"
@@ -40,13 +43,14 @@ func NewMessageThreadHandler(
4043
func (h *MessageThreadHandler) RegisterRoutes(router fiber.Router) {
4144
router.Get("/message-threads", h.Index)
4245
router.Put("/message-threads/:messageThreadID", h.Update)
46+
router.Delete("/message-threads/:messageThreadID", h.Delete)
4347
}
4448

4549
// Index returns message threads for a phone number
4650
// @Summary Get message threads for a phone number
4751
// @Description Get list of contacts which a phone number has communicated with (threads). It will be sorted by timestamp in descending order.
4852
// @Security ApiKeyAuth
49-
// @Tags Channel Threads
53+
// @Tags MessageThreads
5054
// @Accept json
5155
// @Produce json
5256
// @Param owner query string true "owner phone number" default(+18005550199)
@@ -94,7 +98,7 @@ func (h *MessageThreadHandler) Index(c *fiber.Ctx) error {
9498
// @Summary Update a message thread
9599
// @Description Updates the details of a message thread
96100
// @Security ApiKeyAuth
97-
// @Tags Channel Threads
101+
// @Tags MessageThreads
98102
// @Accept json
99103
// @Produce json
100104
// @Param messageThreadID path string true "ID of the message thread" default(32343a19-da5e-4b1b-a767-3298a73703ca)
@@ -106,11 +110,9 @@ func (h *MessageThreadHandler) Index(c *fiber.Ctx) error {
106110
// @Failure 500 {object} responses.InternalServerError
107111
// @Router /message-threads/{messageThreadID} [put]
108112
func (h *MessageThreadHandler) Update(c *fiber.Ctx) error {
109-
ctx, span := h.tracer.StartFromFiberCtx(c)
113+
ctx, span, ctxLogger := h.tracer.StartFromFiberCtxWithLogger(c, h.logger)
110114
defer span.End()
111115

112-
ctxLogger := h.tracer.CtxLogger(h.logger, span)
113-
114116
var request requests.MessageThreadUpdate
115117
if err := c.BodyParser(&request); err != nil {
116118
msg := fmt.Sprintf("cannot marshall params [%s] into %T", c.OriginalURL(), request)
@@ -134,3 +136,49 @@ func (h *MessageThreadHandler) Update(c *fiber.Ctx) error {
134136

135137
return h.responseOK(c, "message thread updated successfully", thread)
136138
}
139+
140+
// Delete a message thread
141+
// @Summary Delete a message thread from the database.
142+
// @Description Delete a message thread from the database and also deletes all the messages in the thread.
143+
// @Security ApiKeyAuth
144+
// @Tags MessageThreads
145+
// @Accept json
146+
// @Produce json
147+
// @Param messageID path string true "ID of the message thread" default(32343a19-da5e-4b1b-a767-3298a73703ca)
148+
// @Success 204 {object} responses.NoContent
149+
// @Failure 400 {object} responses.BadRequest
150+
// @Failure 401 {object} responses.Unauthorized
151+
// @Failure 404 {object} responses.NotFound
152+
// @Failure 422 {object} responses.UnprocessableEntity
153+
// @Failure 500 {object} responses.InternalServerError
154+
// @Router /message-threads/{messageThreadID} [delete]
155+
func (h *MessageThreadHandler) Delete(c *fiber.Ctx) error {
156+
ctx, span, ctxLogger := h.tracer.StartFromFiberCtxWithLogger(c, h.logger)
157+
defer span.End()
158+
159+
messageID := c.Params("messageThreadID")
160+
if errors := h.validator.ValidateUUID(ctx, messageID, "messageThreadID"); len(errors) != 0 {
161+
msg := fmt.Sprintf("validation errors [%s], while deleting a message thread with ID [%s]", spew.Sdump(errors), messageID)
162+
ctxLogger.Warn(stacktrace.NewError(msg))
163+
return h.responseUnprocessableEntity(c, errors, "validation errors while deleting a message thread")
164+
}
165+
166+
message, err := h.service.GetThread(ctx, h.userIDFomContext(c), uuid.MustParse(messageID))
167+
if stacktrace.GetCode(err) == repositories.ErrCodeNotFound {
168+
return h.responseNotFound(c, fmt.Sprintf("cannot find message thread with ID [%s]", messageID))
169+
}
170+
171+
if err != nil {
172+
msg := fmt.Sprintf("cannot find message thread with id [%s]", messageID)
173+
ctxLogger.Error(h.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
174+
return h.responseInternalServerError(c)
175+
}
176+
177+
if err = h.service.DeleteThread(ctx, c.OriginalURL(), message); err != nil {
178+
msg := fmt.Sprintf("cannot delete message thread with ID [%s] for user with ID [%s]", messageID, message.UserID)
179+
ctxLogger.Error(h.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
180+
return h.responseInternalServerError(c)
181+
}
182+
183+
return h.responseNoContent(c, "message thread deleted successfully")
184+
}

0 commit comments

Comments
 (0)