diff --git a/docs/docs.go b/docs/docs.go index ea1abee..cebacdb 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -161,6 +161,54 @@ const docTemplate = `{ } } }, + "/api/v1/whatsapp/send/contact": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Send Contact Message to Spesific Phone Number", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "WhatsApp" + ], + "summary": "Send Contact Message", + "parameters": [ + { + "type": "string", + "description": "Destination Phone Number", + "name": "msisdn", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Contact Name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Contact Phone", + "name": "phone", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/api/v1/whatsapp/send/document": { "post": { "security": [ diff --git a/docs/swagger.json b/docs/swagger.json index fad08c2..015c3a0 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -156,6 +156,54 @@ } } }, + "/api/v1/whatsapp/send/contact": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Send Contact Message to Spesific Phone Number", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "WhatsApp" + ], + "summary": "Send Contact Message", + "parameters": [ + { + "type": "string", + "description": "Destination Phone Number", + "name": "msisdn", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Contact Name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Contact Phone", + "name": "phone", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/api/v1/whatsapp/send/document": { "post": { "security": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index dcf8400..200e576 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -96,6 +96,37 @@ paths: summary: Send Audio Message tags: - WhatsApp + /api/v1/whatsapp/send/contact: + post: + consumes: + - multipart/form-data + description: Send Contact Message to Spesific Phone Number + parameters: + - description: Destination Phone Number + in: formData + name: msisdn + required: true + type: string + - description: Contact Name + in: formData + name: name + required: true + type: string + - description: Contact Phone + in: formData + name: phone + required: true + type: string + produces: + - application/json + responses: + "200": + description: "" + security: + - BearerAuth: [] + summary: Send Contact Message + tags: + - WhatsApp /api/v1/whatsapp/send/document: post: consumes: diff --git a/internal/route.go b/internal/route.go index 48189a7..19f8d22 100644 --- a/internal/route.go +++ b/internal/route.go @@ -38,6 +38,7 @@ func Routes(e *echo.Echo) { e.POST(router.BaseURL+"/login", ctlWhatsApp.Login, middleware.JWTWithConfig(authJWTConfig)) 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/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 ff33ca1..994cfc5 100644 --- a/internal/whatsapp/types/request.go +++ b/internal/whatsapp/types/request.go @@ -14,3 +14,9 @@ type RequestSendLocation struct { Latitude float64 Longitude float64 } + +type RequestSendContact struct { + RJID string + Name string + Phone string +} diff --git a/internal/whatsapp/whatsapp.go b/internal/whatsapp/whatsapp.go index 731a9a1..125bfcc 100644 --- a/internal/whatsapp/whatsapp.go +++ b/internal/whatsapp/whatsapp.go @@ -147,6 +147,10 @@ func SendText(c echo.Context) error { return router.ResponseBadRequest(c, "Missing Form Value MSISDN") } + if len(reqSendMessage.Message) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value Message") + } + var resSendMessage typWhatsApp.ResponseSendMessage resSendMessage.MsgID, err = pkgWhatsApp.WhatsAppSendText(jid, reqSendMessage.RJID, reqSendMessage.Message) if err != nil { @@ -198,6 +202,48 @@ func SendLocation(c echo.Context) error { return router.ResponseSuccessWithData(c, "Successfully Send Location Message", resSendMessage) } +// SendContact +// @Summary Send Contact Message +// @Description Send Contact Message to Spesific Phone Number +// @Tags WhatsApp +// @Accept multipart/form-data +// @Produce json +// @Param msisdn formData string true "Destination Phone Number" +// @Param name formData string true "Contact Name" +// @Param phone formData string true "Contact Phone" +// @Success 200 +// @Security BearerAuth +// @Router /api/v1/whatsapp/send/contact [post] +func SendContact(c echo.Context) error { + var err error + jid := jwtPayload(c).JID + + var reqSendContact typWhatsApp.RequestSendContact + reqSendContact.RJID = strings.TrimSpace(c.FormValue("msisdn")) + reqSendContact.Name = strings.TrimSpace(c.FormValue("name")) + reqSendContact.Phone = strings.TrimSpace(c.FormValue("phone")) + + if len(reqSendContact.RJID) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value MSISDN") + } + + if len(reqSendContact.Name) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value Name") + } + + if len(reqSendContact.Phone) == 0 { + return router.ResponseBadRequest(c, "Missing Form Value Phone") + } + + var resSendMessage typWhatsApp.ResponseSendMessage + resSendMessage.MsgID, err = pkgWhatsApp.WhatsAppSendContact(jid, reqSendContact.RJID, reqSendContact.Name, reqSendContact.Phone) + if err != nil { + return router.ResponseInternalError(c, err.Error()) + } + + return router.ResponseSuccessWithData(c, "Successfully Send Contact Message", resSendMessage) +} + // SendDocument // @Summary Send Document Message // @Description Send Document Message to Spesific Phone Number diff --git a/pkg/whatsapp/whatsapp.go b/pkg/whatsapp/whatsapp.go index 3b09002..093fd14 100644 --- a/pkg/whatsapp/whatsapp.go +++ b/pkg/whatsapp/whatsapp.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "errors" + "fmt" "strings" qrCode "github.com/skip2/go-qrcode" @@ -556,3 +557,44 @@ func WhatsAppSendVideo(jid string, rjid string, videoBytes []byte, videoType str // Return Error WhatsApp Client is not Valid return "", errors.New("WhatsApp Client is not Valid") } + +func WhatsAppSendContact(jid string, rjid string, contactName string, contactNumber 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() + msgVCard := fmt.Sprintf("BEGIN:VCARD\nVERSION:3.0\nN:;%v;;;\nFN:%v\nTEL;type=CELL;waid=%v:+%v\nEND:VCARD", + contactName, contactName, contactNumber, contactNumber) + msgContent := &waproto.Message{ + ContactMessage: &waproto.ContactMessage{ + DisplayName: proto.String(contactName), + Vcard: proto.String(msgVCard), + }, + } + + // 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") +}