File size: 4,772 Bytes
c099d87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b0b934b
c099d87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75af2b7
c099d87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b0b934b
c099d87
 
 
 
 
 
 
 
 
b0b934b
c099d87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b0b934b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package controllers

import (
	"whatsapp-backend/models/dto"
	http_error "whatsapp-backend/models/error"
	"whatsapp-backend/services"
	"whatsapp-backend/utils"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type ChatController interface {
	FetchContacts(ctx *gin.Context)
	SendMessage(ctx *gin.Context)
	SendImage(ctx *gin.Context)
}

type chatController struct {
	chatService services.ChatService
}

func NewChatController(chatService services.ChatService) ChatController {
	return &chatController{chatService}
}

// FetchContacts godoc
// @Summary      Fetch WhatsApp contacts
// @Description  Fetch list of contacts from the connected WhatsApp account
// @Tags         chat
// @Security     BearerAuth
// @Accept       json
// @Produce      json
// @Success      200  {object}  dto.FetchContactsResponse
// @Failure      401  {object}  dto.ErrorResponse
// @Failure      400  {object}  dto.ErrorResponse
// @Router       /chat/contacts [get]
func (c *chatController) FetchContacts(ctx *gin.Context) {
	userID, exists := ctx.Get("user_id")
	if !exists {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.UNAUTHORIZED)
		return
	}
	accountID := userID.(uuid.UUID)

	contacts, err := c.chatService.FetchContacts(ctx, accountID)
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, err)
		return
	}

	response := dto.FetchContactsResponse{
		AccountID: accountID,
		Contacts:  contacts,
	}

	utils.SendResponse[dto.FetchContactsResponse, any](ctx, nil, response, nil)
}

// SendMessage godoc
// @Summary      Send WhatsApp text message
// @Description  Send a text message to a WhatsApp number
// @Tags         chat
// @Security     BearerAuth
// @Accept       json
// @Produce      json
// @Param        request body dto.SendMessageRequest true "Send Message Request"
// @Success      200  {object}  dto.SendMessageResponse
// @Failure      401  {object}  dto.ErrorResponse
// @Failure      400  {object}  dto.ErrorResponse
// @Router       /chat/send_msg [post]
func (c *chatController) SendMessage(ctx *gin.Context) {
	userID, exists := ctx.Get("user_id")
	if !exists {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.UNAUTHORIZED)
		return
	}
	accountID := userID.(uuid.UUID)

	var req dto.SendMessageRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.ERR_BAD_REQUEST)
		return
	}

	msgID, err := c.chatService.SendMessage(ctx, accountID, req.Recipient, req.Message)
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, err)
		return
	}

	response := dto.SendMessageResponse{
		MessageID: msgID,
		Status:    "SENT",
	}

	utils.SendResponse[dto.SendMessageResponse, any](ctx, nil, response, nil)
}

// SendImage godoc
// @Summary      Send WhatsApp image
// @Description  Send an image to a WhatsApp number via file upload
// @Tags         chat
// @Security     BearerAuth
// @Accept       multipart/form-data
// @Produce      json
// @Param        image formData file true "Image file to send"
// @Param        recipient formData string true "Recipient phone number" example(628123456789)
// @Param        caption formData string false "Image caption"
// @Success      200  {object}  dto.SendMessageResponse
// @Failure      401  {object}  dto.ErrorResponse
// @Failure      400  {object}  dto.ErrorResponse
// @Router       /chat/send_img [post]
func (c *chatController) SendImage(ctx *gin.Context) {
	userID, exists := ctx.Get("user_id")
	if !exists {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.UNAUTHORIZED)
		return
	}
	accountID := userID.(uuid.UUID)

	// Get form values
	recipient := ctx.PostForm("recipient")
	caption := ctx.PostForm("caption")

	if recipient == "" {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.ERR_BAD_REQUEST)
		return
	}

	// Get uploaded file
	file, err := ctx.FormFile("image")
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.ERR_BAD_REQUEST)
		return
	}

	// Open file
	src, err := file.Open()
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.ERR_BAD_REQUEST)
		return
	}
	defer src.Close()

	// Read file content
	imageData := make([]byte, file.Size)
	_, err = src.Read(imageData)
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, http_error.ERR_BAD_REQUEST)
		return
	}

	// Get mimetype from header
	mimetype := file.Header.Get("Content-Type")
	if mimetype == "" {
		mimetype = "image/jpeg"
	}

	msgID, err := c.chatService.SendImage(ctx, accountID, recipient, imageData, mimetype, caption)
	if err != nil {
		utils.SendResponse[any, any](ctx, nil, nil, err)
		return
	}

	response := dto.SendMessageResponse{
		MessageID: msgID,
		Status:    "SENT",
	}

	utils.SendResponse[dto.SendMessageResponse, any](ctx, nil, response, nil)
}