From a9e80e09aab5e5629285cd67d42bf63fe887db37 Mon Sep 17 00:00:00 2001 From: Dimas Restu H Date: Tue, 10 May 2022 14:46:28 +0700 Subject: [PATCH] add capabilities to send link (but still no preview) --- docs/docs.go | 65 +++++++++++++++++++++++++----- docs/swagger.json | 65 +++++++++++++++++++++++++----- docs/swagger.yaml | 48 +++++++++++++++++----- internal/route.go | 1 + internal/whatsapp/types/request.go | 6 +++ internal/whatsapp/whatsapp.go | 56 ++++++++++++++++++++----- pkg/whatsapp/whatsapp.go | 53 ++++++++++++++++++++++++ 7 files changed, 258 insertions(+), 36 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index cebacdb..611eecc 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -75,7 +75,7 @@ const docTemplate = `{ "text/html" ], "tags": [ - "WhatsApp" + "WhatsApp Authentication" ], "summary": "Generate QR Code for WhatsApp Multi-Device Login", "parameters": [ @@ -110,7 +110,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Authentication" ], "summary": "Logout Device from WhatsApp Multi-Device", "responses": { @@ -135,7 +135,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Audio Message", "parameters": [ @@ -176,7 +176,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Contact Message", "parameters": [ @@ -224,7 +224,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Document Message", "parameters": [ @@ -265,7 +265,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Image Message", "parameters": [ @@ -298,6 +298,53 @@ const docTemplate = `{ } } }, + "/api/v1/whatsapp/send/link": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Send Link Message to Spesific Phone Number", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "WhatsApp Message" + ], + "summary": "Send Link Message", + "parameters": [ + { + "type": "string", + "description": "Destination Phone Number", + "name": "msisdn", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Link Caption", + "name": "caption", + "in": "formData" + }, + { + "type": "string", + "description": "Link URL", + "name": "url", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/api/v1/whatsapp/send/location": { "post": { "security": [ @@ -313,7 +360,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Location Message", "parameters": [ @@ -361,7 +408,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Text Message", "parameters": [ @@ -402,7 +449,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Video Message", "parameters": [ diff --git a/docs/swagger.json b/docs/swagger.json index 015c3a0..0b5793c 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -70,7 +70,7 @@ "text/html" ], "tags": [ - "WhatsApp" + "WhatsApp Authentication" ], "summary": "Generate QR Code for WhatsApp Multi-Device Login", "parameters": [ @@ -105,7 +105,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Authentication" ], "summary": "Logout Device from WhatsApp Multi-Device", "responses": { @@ -130,7 +130,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Audio Message", "parameters": [ @@ -171,7 +171,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Contact Message", "parameters": [ @@ -219,7 +219,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Document Message", "parameters": [ @@ -260,7 +260,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Image Message", "parameters": [ @@ -293,6 +293,53 @@ } } }, + "/api/v1/whatsapp/send/link": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Send Link Message to Spesific Phone Number", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "WhatsApp Message" + ], + "summary": "Send Link Message", + "parameters": [ + { + "type": "string", + "description": "Destination Phone Number", + "name": "msisdn", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Link Caption", + "name": "caption", + "in": "formData" + }, + { + "type": "string", + "description": "Link URL", + "name": "url", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/api/v1/whatsapp/send/location": { "post": { "security": [ @@ -308,7 +355,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Location Message", "parameters": [ @@ -356,7 +403,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Text Message", "parameters": [ @@ -397,7 +444,7 @@ "application/json" ], "tags": [ - "WhatsApp" + "WhatsApp Message" ], "summary": "Send Video Message", "parameters": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 200e576..621147c 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -56,7 +56,7 @@ paths: - BearerAuth: [] summary: Generate QR Code for WhatsApp Multi-Device Login tags: - - WhatsApp + - WhatsApp Authentication /api/v1/whatsapp/logout: post: description: Make Device Logout from WhatsApp Multi-Device @@ -69,7 +69,7 @@ paths: - BearerAuth: [] summary: Logout Device from WhatsApp Multi-Device tags: - - WhatsApp + - WhatsApp Authentication /api/v1/whatsapp/send/audio: post: consumes: @@ -95,7 +95,7 @@ paths: - BearerAuth: [] summary: Send Audio Message tags: - - WhatsApp + - WhatsApp Message /api/v1/whatsapp/send/contact: post: consumes: @@ -126,7 +126,7 @@ paths: - BearerAuth: [] summary: Send Contact Message tags: - - WhatsApp + - WhatsApp Message /api/v1/whatsapp/send/document: post: consumes: @@ -152,7 +152,7 @@ paths: - BearerAuth: [] summary: Send Document Message tags: - - WhatsApp + - WhatsApp Message /api/v1/whatsapp/send/image: post: consumes: @@ -183,7 +183,37 @@ paths: - BearerAuth: [] summary: Send Image Message tags: - - WhatsApp + - WhatsApp Message + /api/v1/whatsapp/send/link: + post: + consumes: + - multipart/form-data + description: Send Link Message to Spesific Phone Number + parameters: + - description: Destination Phone Number + in: formData + name: msisdn + required: true + type: string + - description: Link Caption + in: formData + name: caption + type: string + - description: Link URL + in: formData + name: url + required: true + type: string + produces: + - application/json + responses: + "200": + description: "" + security: + - BearerAuth: [] + summary: Send Link Message + tags: + - WhatsApp Message /api/v1/whatsapp/send/location: post: consumes: @@ -214,7 +244,7 @@ paths: - BearerAuth: [] summary: Send Location Message tags: - - WhatsApp + - WhatsApp Message /api/v1/whatsapp/send/text: post: consumes: @@ -240,7 +270,7 @@ paths: - BearerAuth: [] summary: Send Text Message tags: - - WhatsApp + - WhatsApp Message /api/v1/whatsapp/send/video: post: consumes: @@ -271,7 +301,7 @@ paths: - BearerAuth: [] summary: Send Video Message tags: - - WhatsApp + - WhatsApp Message schemes: - http securityDefinitions: diff --git a/internal/route.go b/internal/route.go index 19f8d22..837718e 100644 --- a/internal/route.go +++ b/internal/route.go @@ -39,6 +39,7 @@ func Routes(e *echo.Echo) { e.POST(router.BaseURL+"/send/text", ctlWhatsApp.SendText, middleware.JWTWithConfig(authJWTConfig)) e.POST(router.BaseURL+"/send/location", ctlWhatsApp.SendLocation, middleware.JWTWithConfig(authJWTConfig)) e.POST(router.BaseURL+"/send/contact", ctlWhatsApp.SendContact, middleware.JWTWithConfig(authJWTConfig)) + e.POST(router.BaseURL+"/send/link", ctlWhatsApp.SendLink, middleware.JWTWithConfig(authJWTConfig)) e.POST(router.BaseURL+"/send/document", ctlWhatsApp.SendDocument, middleware.JWTWithConfig(authJWTConfig)) e.POST(router.BaseURL+"/send/image", ctlWhatsApp.SendImage, middleware.JWTWithConfig(authJWTConfig)) e.POST(router.BaseURL+"/send/audio", ctlWhatsApp.SendAudio, middleware.JWTWithConfig(authJWTConfig)) diff --git a/internal/whatsapp/types/request.go b/internal/whatsapp/types/request.go index 994cfc5..7586965 100644 --- a/internal/whatsapp/types/request.go +++ b/internal/whatsapp/types/request.go @@ -20,3 +20,9 @@ type RequestSendContact struct { Name string Phone string } + +type RequestSendLink struct { + RJID string + Caption string + URL string +} diff --git a/internal/whatsapp/whatsapp.go b/internal/whatsapp/whatsapp.go index 125bfcc..1b65c0f 100644 --- a/internal/whatsapp/whatsapp.go +++ b/internal/whatsapp/whatsapp.go @@ -43,7 +43,7 @@ func convertFileToBytes(file multipart.File) ([]byte, error) { // Login // @Summary Generate QR Code for WhatsApp Multi-Device Login // @Description Get QR Code for WhatsApp Multi-Device Login -// @Tags WhatsApp +// @Tags WhatsApp Authentication // @Accept multipart/form-data // @Produce json // @Produce html @@ -107,7 +107,7 @@ func Login(c echo.Context) error { // Logout // @Summary Logout Device from WhatsApp Multi-Device // @Description Make Device Logout from WhatsApp Multi-Device -// @Tags WhatsApp +// @Tags WhatsApp Authentication // @Produce json // @Success 200 // @Security BearerAuth @@ -127,7 +127,7 @@ func Logout(c echo.Context) error { // SendText // @Summary Send Text Message // @Description Send Text Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -163,7 +163,7 @@ func SendText(c echo.Context) error { // SendLocation // @Summary Send Location Message // @Description Send Location Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -205,7 +205,7 @@ func SendLocation(c echo.Context) error { // SendContact // @Summary Send Contact Message // @Description Send Contact Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -244,10 +244,48 @@ func SendContact(c echo.Context) error { return router.ResponseSuccessWithData(c, "Successfully Send Contact Message", resSendMessage) } +// SendLink +// @Summary Send Link Message +// @Description Send Link Message to Spesific Phone Number +// @Tags WhatsApp Message +// @Accept multipart/form-data +// @Produce json +// @Param msisdn formData string true "Destination Phone Number" +// @Param caption formData string false "Link Caption" +// @Param url formData string true "Link URL" +// @Success 200 +// @Security BearerAuth +// @Router /api/v1/whatsapp/send/link [post] +func SendLink(c echo.Context) error { + var err error + jid := jwtPayload(c).JID + + var reqSendLink typWhatsApp.RequestSendLink + reqSendLink.RJID = strings.TrimSpace(c.FormValue("msisdn")) + reqSendLink.Caption = strings.TrimSpace(c.FormValue("caption")) + reqSendLink.URL = strings.TrimSpace(c.FormValue("url")) + + if len(reqSendLink.RJID) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value MSISDN") + } + + if len(reqSendLink.URL) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value URL") + } + + var resSendMessage typWhatsApp.ResponseSendMessage + resSendMessage.MsgID, err = pkgWhatsApp.WhatsAppSendLink(jid, reqSendLink.RJID, reqSendLink.Caption, reqSendLink.URL) + if err != nil { + return router.ResponseInternalError(c, err.Error()) + } + + return router.ResponseSuccessWithData(c, "Successfully Send Link Message", resSendMessage) +} + // SendDocument // @Summary Send Document Message // @Description Send Document Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -262,7 +300,7 @@ func SendDocument(c echo.Context) error { // SendImage // @Summary Send Image Message // @Description Send Image Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -278,7 +316,7 @@ func SendImage(c echo.Context) error { // SendAudio // @Summary Send Audio Message // @Description Send Audio Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" @@ -293,7 +331,7 @@ func SendAudio(c echo.Context) error { // SendVideo // @Summary Send Video Message // @Description Send Video Message to Spesific Phone Number -// @Tags WhatsApp +// @Tags WhatsApp Message // @Accept multipart/form-data // @Produce json // @Param msisdn formData string true "Destination Phone Number" diff --git a/pkg/whatsapp/whatsapp.go b/pkg/whatsapp/whatsapp.go index 093fd14..d3099da 100644 --- a/pkg/whatsapp/whatsapp.go +++ b/pkg/whatsapp/whatsapp.go @@ -598,3 +598,56 @@ func WhatsAppSendContact(jid string, rjid string, contactName string, contactNum // Return Error WhatsApp Client is not Valid return "", errors.New("WhatsApp Client is not Valid") } + +func WhatsAppSendLink(jid string, rjid string, linkCaption string, linkURL string) (string, error) { + if WhatsAppClient[jid] != nil { + var err error + + // Make Sure WhatsApp Client is OK + err = WhatsAppClientIsOK(jid) + if err != nil { + return "", err + } + + // Make Sure Remote JID is Proper JID Type + remoteJID := WhatsAppComposeJID(rjid) + + // Set Chat Presence + WhatsAppComposeStatus(jid, remoteJID, true, false) + defer WhatsAppComposeStatus(jid, remoteJID, false, false) + + // Compose WhatsApp Proto + msgId := whatsmeow.GenerateMessageID() + msgCaption := "Open Link" + msgText := linkURL + + if len(strings.TrimSpace(linkCaption)) > 0 { + msgCaption = linkCaption + msgText = fmt.Sprintf("%s\n%s", linkCaption, linkURL) + } + + msgContent := &waproto.Message{ + ExtendedTextMessage: &waproto.ExtendedTextMessage{ + Text: proto.String(msgText), + CanonicalUrl: proto.String(linkURL), + ContextInfo: &waproto.ContextInfo{ + ActionLink: &waproto.ActionLink{ + Url: proto.String(linkURL), + ButtonTitle: proto.String(msgCaption), + }, + }, + }, + } + + // Send WhatsApp Message Proto + _, err = WhatsAppClient[jid].SendMessage(remoteJID, msgId, msgContent) + if err != nil { + return "", err + } + + return msgId, nil + } + + // Return Error WhatsApp Client is not Valid + return "", errors.New("WhatsApp Client is not Valid") +}