Skip to content

Commit

Permalink
Add the ability to delete threads and all messages #322
Browse files Browse the repository at this point in the history
  • Loading branch information
AchoArnold committed Jan 11, 2024
1 parent 8c030b6 commit 6602902
Show file tree
Hide file tree
Showing 17 changed files with 449 additions and 19 deletions.
70 changes: 68 additions & 2 deletions api/docs/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 62 additions & 2 deletions api/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@
"description": "Get list of contacts which a phone number has communicated with (threads). It will be sorted by timestamp in descending order.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Channel Threads"],
"tags": ["MessageThreads"],
"summary": "Get message threads for a phone number",
"parameters": [
{
Expand Down Expand Up @@ -757,7 +757,7 @@
"description": "Updates the details of a message thread",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Channel Threads"],
"tags": ["MessageThreads"],
"summary": "Update a message thread",
"parameters": [
{
Expand Down Expand Up @@ -810,6 +810,66 @@
}
}
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Delete a message thread from the database and also deletes all the messages in the thread.",
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["MessageThreads"],
"summary": "Delete a message thread from the database.",
"parameters": [
{
"type": "string",
"default": "32343a19-da5e-4b1b-a767-3298a73703ca",
"description": "ID of the message thread",
"name": "messageID",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content",
"schema": {
"$ref": "#/definitions/responses.NoContent"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/responses.BadRequest"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/responses.Unauthorized"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/responses.NotFound"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/responses.UnprocessableEntity"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/responses.InternalServerError"
}
}
}
}
},
"/messages": {
Expand Down
49 changes: 47 additions & 2 deletions api/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1594,8 +1594,53 @@ paths:
- ApiKeyAuth: []
summary: Get message threads for a phone number
tags:
- Channel Threads
- MessageThreads
/message-threads/{messageThreadID}:
delete:
consumes:
- application/json
description:
Delete a message thread from the database and also deletes all
the messages in the thread.
parameters:
- default: 32343a19-da5e-4b1b-a767-3298a73703ca
description: ID of the message thread
in: path
name: messageID
required: true
type: string
produces:
- application/json
responses:
"204":
description: No Content
schema:
$ref: "#/definitions/responses.NoContent"
"400":
description: Bad Request
schema:
$ref: "#/definitions/responses.BadRequest"
"401":
description: Unauthorized
schema:
$ref: "#/definitions/responses.Unauthorized"
"404":
description: Not Found
schema:
$ref: "#/definitions/responses.NotFound"
"422":
description: Unprocessable Entity
schema:
$ref: "#/definitions/responses.UnprocessableEntity"
"500":
description: Internal Server Error
schema:
$ref: "#/definitions/responses.InternalServerError"
security:
- ApiKeyAuth: []
summary: Delete a message thread from the database.
tags:
- MessageThreads
put:
consumes:
- application/json
Expand Down Expand Up @@ -1640,7 +1685,7 @@ paths:
- ApiKeyAuth: []
summary: Update a message thread
tags:
- Channel Threads
- MessageThreads
/messages:
get:
consumes:
Expand Down
1 change: 1 addition & 0 deletions api/pkg/di/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,7 @@ func (container *Container) MessageThreadService() (service *services.MessageThr
container.Logger(),
container.Tracer(),
container.MessageThreadRepository(),
container.EventDispatcher(),
)
}

Expand Down
24 changes: 24 additions & 0 deletions api/pkg/events/message_thead_api_deleted_event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package events

import (
"time"

"github.com/NdoleStudio/httpsms/pkg/entities"

"github.com/google/uuid"
)

// MessageThreadAPIDeleted is emitted when a new message is deleted
const MessageThreadAPIDeleted = "message-thread.api.deleted"

// MessageThreadAPIDeletedPayload is the payload of the MessageThreadAPIDeleted event
type MessageThreadAPIDeletedPayload struct {
MessageThreadID uuid.UUID `json:"message_thread_id"`
UserID entities.UserID `json:"user_id"`
Owner string `json:"owner"`
Contact string `json:"contact"`
IsArchived bool `json:"is_archived"`
Color string `json:"color"`
Status entities.MessageStatus `json:"status"`
Timestamp time.Time `json:"timestamp"`
}
58 changes: 53 additions & 5 deletions api/pkg/handlers/message_thread_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package handlers
import (
"fmt"

"github.com/NdoleStudio/httpsms/pkg/repositories"
"github.com/google/uuid"

"github.com/NdoleStudio/httpsms/pkg/requests"
"github.com/NdoleStudio/httpsms/pkg/services"
"github.com/NdoleStudio/httpsms/pkg/telemetry"
Expand Down Expand Up @@ -40,13 +43,14 @@ func NewMessageThreadHandler(
func (h *MessageThreadHandler) RegisterRoutes(router fiber.Router) {
router.Get("/message-threads", h.Index)
router.Put("/message-threads/:messageThreadID", h.Update)
router.Delete("/message-threads/:messageThreadID", h.Delete)
}

// Index returns message threads for a phone number
// @Summary Get message threads for a phone number
// @Description Get list of contacts which a phone number has communicated with (threads). It will be sorted by timestamp in descending order.
// @Security ApiKeyAuth
// @Tags Channel Threads
// @Tags MessageThreads
// @Accept json
// @Produce json
// @Param owner query string true "owner phone number" default(+18005550199)
Expand Down Expand Up @@ -94,7 +98,7 @@ func (h *MessageThreadHandler) Index(c *fiber.Ctx) error {
// @Summary Update a message thread
// @Description Updates the details of a message thread
// @Security ApiKeyAuth
// @Tags Channel Threads
// @Tags MessageThreads
// @Accept json
// @Produce json
// @Param messageThreadID path string true "ID of the message thread" default(32343a19-da5e-4b1b-a767-3298a73703ca)
Expand All @@ -106,11 +110,9 @@ func (h *MessageThreadHandler) Index(c *fiber.Ctx) error {
// @Failure 500 {object} responses.InternalServerError
// @Router /message-threads/{messageThreadID} [put]
func (h *MessageThreadHandler) Update(c *fiber.Ctx) error {
ctx, span := h.tracer.StartFromFiberCtx(c)
ctx, span, ctxLogger := h.tracer.StartFromFiberCtxWithLogger(c, h.logger)
defer span.End()

ctxLogger := h.tracer.CtxLogger(h.logger, span)

var request requests.MessageThreadUpdate
if err := c.BodyParser(&request); err != nil {
msg := fmt.Sprintf("cannot marshall params [%s] into %T", c.OriginalURL(), request)
Expand All @@ -134,3 +136,49 @@ func (h *MessageThreadHandler) Update(c *fiber.Ctx) error {

return h.responseOK(c, "message thread updated successfully", thread)
}

// Delete a message thread
// @Summary Delete a message thread from the database.
// @Description Delete a message thread from the database and also deletes all the messages in the thread.
// @Security ApiKeyAuth
// @Tags MessageThreads
// @Accept json
// @Produce json
// @Param messageID path string true "ID of the message thread" default(32343a19-da5e-4b1b-a767-3298a73703ca)
// @Success 204 {object} responses.NoContent
// @Failure 400 {object} responses.BadRequest
// @Failure 401 {object} responses.Unauthorized
// @Failure 404 {object} responses.NotFound
// @Failure 422 {object} responses.UnprocessableEntity
// @Failure 500 {object} responses.InternalServerError
// @Router /message-threads/{messageThreadID} [delete]
func (h *MessageThreadHandler) Delete(c *fiber.Ctx) error {
ctx, span, ctxLogger := h.tracer.StartFromFiberCtxWithLogger(c, h.logger)
defer span.End()

messageID := c.Params("messageThreadID")
if errors := h.validator.ValidateUUID(ctx, messageID, "messageThreadID"); len(errors) != 0 {
msg := fmt.Sprintf("validation errors [%s], while deleting a message thread with ID [%s]", spew.Sdump(errors), messageID)
ctxLogger.Warn(stacktrace.NewError(msg))
return h.responseUnprocessableEntity(c, errors, "validation errors while deleting a message thread")
}

message, err := h.service.GetThread(ctx, h.userIDFomContext(c), uuid.MustParse(messageID))
if stacktrace.GetCode(err) == repositories.ErrCodeNotFound {
return h.responseNotFound(c, fmt.Sprintf("cannot find message thread with ID [%s]", messageID))
}

if err != nil {
msg := fmt.Sprintf("cannot find message thread with id [%s]", messageID)
ctxLogger.Error(h.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
return h.responseInternalServerError(c)
}

if err = h.service.DeleteThread(ctx, c.OriginalURL(), message); err != nil {
msg := fmt.Sprintf("cannot delete message thread with ID [%s] for user with ID [%s]", messageID, message.UserID)
ctxLogger.Error(h.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg)))
return h.responseInternalServerError(c)
}

return h.responseNoContent(c, "message thread deleted successfully")
}
Loading

0 comments on commit 6602902

Please sign in to comment.