Browse Source

feat: add send location

pull/43/head
Aldino Kemal 3 years ago
parent
commit
84a7df28c6
  1. 45
      docs/openapi.yaml
  2. 12
      src/domains/send/location.go
  3. 1
      src/domains/send/send.go
  4. 18
      src/internal/rest/send.go
  5. 10
      src/pkg/utils/general.go
  6. 30
      src/services/send.go
  7. 15
      src/validations/send_validation.go
  8. 74
      src/validations/send_validation_test.go

45
docs/openapi.yaml

@ -1,7 +1,7 @@
openapi: 3.0.0
info:
title: WhatsApp API MultiDevice
version: 3.0.0
version: 3.1.0
description: This API is used for sending whatsapp via API
servers:
- url: http://localhost:3000
@ -566,6 +566,49 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorInternalServer'
/send/location:
post:
operationId: sendLocation
tags:
- message
summary: Send Location
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
phone:
type: integer
example: '6289685024051@s.whatsapp.net'
description: Phone number with country code
latitude:
type: string
example: "-7.797068"
description: Latitude coordinate
longitude:
type: string
example: '110.370529'
description: Longitude coordinate
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/SendResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBadRequest'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorInternalServer'
/message/:message_id/revoke:
post:
operationId: revokeMessage

12
src/domains/send/location.go

@ -0,0 +1,12 @@
package send
type LocationRequest struct {
Phone string `json:"phone" form:"phone"`
Latitude string `json:"latitude" form:"latitude"`
Longitude string `json:"longitude" form:"longitude"`
}
type LocationResponse struct {
MessageID string `json:"message_id"`
Status string `json:"status"`
}

1
src/domains/send/send.go

@ -11,6 +11,7 @@ type ISendService interface {
SendVideo(ctx context.Context, request VideoRequest) (response VideoResponse, err error)
SendContact(ctx context.Context, request ContactRequest) (response ContactResponse, err error)
SendLink(ctx context.Context, request LinkRequest) (response LinkResponse, err error)
SendLocation(ctx context.Context, request LocationRequest) (response LocationResponse, err error)
Revoke(ctx context.Context, request RevokeRequest) (response RevokeResponse, err error)
UpdateMessage(ctx context.Context, request UpdateMessageRequest) (response UpdateMessageResponse, err error)
}

18
src/internal/rest/send.go

@ -19,6 +19,7 @@ func InitRestSend(app *fiber.App, service domainSend.ISendService) Send {
app.Post("/send/video", rest.SendVideo)
app.Post("/send/contact", rest.SendContact)
app.Post("/send/link", rest.SendLink)
app.Post("/send/location", rest.SendLocation)
app.Post("/message/:message_id/revoke", rest.RevokeMessage)
app.Post("/message/:message_id/update", rest.UpdateMessage)
return rest
@ -140,6 +141,23 @@ func (controller *Send) SendLink(c *fiber.Ctx) error {
})
}
func (controller *Send) SendLocation(c *fiber.Ctx) error {
var request domainSend.LocationRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
whatsapp.SanitizePhone(&request.Phone)
response, err := controller.Service.SendLocation(c.UserContext(), request)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{
Status: 200,
Message: response.Status,
Results: response,
})
}
func (controller *Send) RevokeMessage(c *fiber.Ctx) error {
var request domainSend.RevokeRequest
err := c.BodyParser(&request)

10
src/pkg/utils/general.go

@ -4,6 +4,8 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
)
@ -46,3 +48,11 @@ func PanicIfNeeded(err any, message ...string) {
}
}
}
func StrToFloat64(text string) float64 {
var result float64
if text != "" {
result, _ = strconv.ParseFloat(strings.TrimSpace(text), 64)
}
return result
}

30
src/services/send.go

@ -372,6 +372,36 @@ func (service serviceSend) SendLink(ctx context.Context, request domainSend.Link
return response, nil
}
func (service serviceSend) SendLocation(ctx context.Context, request domainSend.LocationRequest) (response domainSend.LocationResponse, err error) {
err = validations.ValidateSendLocation(ctx, request)
if err != nil {
return response, err
}
dataWaRecipient, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.Phone)
if err != nil {
return response, err
}
// Compose WhatsApp Proto
msgId := whatsmeow.GenerateMessageID()
msg := &waProto.Message{
LocationMessage: &waProto.LocationMessage{
DegreesLatitude: proto.Float64(utils.StrToFloat64(request.Latitude)),
DegreesLongitude: proto.Float64(utils.StrToFloat64(request.Longitude)),
},
}
// Send WhatsApp Message Proto
ts, err := service.WaCli.SendMessage(ctx, dataWaRecipient, msgId, msg)
if err != nil {
return response, err
}
response.MessageID = msgId
response.Status = fmt.Sprintf("Send location success %s (server timestamp: %s)", request.Phone, ts)
return response, nil
}
func (service serviceSend) Revoke(_ context.Context, request domainSend.RevokeRequest) (response domainSend.RevokeResponse, err error) {
err = validations.ValidateRevokeMessage(request)
if err != nil {

15
src/validations/send_validation.go

@ -1,6 +1,7 @@
package validations
import (
"context"
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
@ -119,6 +120,20 @@ func ValidateSendLink(request domainSend.LinkRequest) error {
return nil
}
func ValidateSendLocation(ctx context.Context, request domainSend.LocationRequest) error {
err := validation.ValidateStructWithContext(ctx, &request,
validation.Field(&request.Phone, validation.Required),
validation.Field(&request.Latitude, validation.Required, is.Latitude),
validation.Field(&request.Longitude, validation.Required, is.Longitude),
)
if err != nil {
return pkgError.ValidationError(err.Error())
}
return nil
}
func ValidateRevokeMessage(request domainSend.RevokeRequest) error {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required),

74
src/validations/send_validation_test.go

@ -1,6 +1,7 @@
package validations
import (
"context"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error"
"github.com/stretchr/testify/assert"
@ -453,3 +454,76 @@ func TestValidateSendContact(t *testing.T) {
})
}
}
func TestValidateSendLocation(t *testing.T) {
type args struct {
request domainSend.LocationRequest
}
tests := []struct {
name string
args args
err any
}{
{
name: "should success normal condition",
args: args{request: domainSend.LocationRequest{
Phone: "1728937129312@s.whatsapp.net",
Latitude: "-7.797068",
Longitude: "110.370529",
}},
err: nil,
},
{
name: "should error with empty phone",
args: args{request: domainSend.LocationRequest{
Phone: "",
Latitude: "-7.797068",
Longitude: "110.370529",
}},
err: pkgError.ValidationError("phone: cannot be blank."),
},
{
name: "should error with empty latitude",
args: args{request: domainSend.LocationRequest{
Phone: "1728937129312@s.whatsapp.net",
Latitude: "",
Longitude: "110.370529",
}},
err: pkgError.ValidationError("latitude: cannot be blank."),
},
{
name: "should error with empty longitude",
args: args{request: domainSend.LocationRequest{
Phone: "1728937129312@s.whatsapp.net",
Latitude: "-7.797068",
Longitude: "",
}},
err: pkgError.ValidationError("longitude: cannot be blank."),
},
{
name: "should error with invalid latitude",
args: args{request: domainSend.LocationRequest{
Phone: "1728937129312@s.whatsapp.net",
Latitude: "ABCDEF",
Longitude: "110.370529",
}},
err: pkgError.ValidationError("latitude: must be a valid latitude."),
},
{
name: "should error with invalid latitude",
args: args{request: domainSend.LocationRequest{
Phone: "1728937129312@s.whatsapp.net",
Latitude: "-7.797068",
Longitude: "ABCDEF",
}},
err: pkgError.ValidationError("longitude: must be a valid longitude."),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateSendLocation(context.Background(), tt.args.request)
assert.Equal(t, tt.err, err)
})
}
}
Loading…
Cancel
Save