Browse Source

feat: add api login with code

pull/171/head
Aldino Kemal 2 years ago
parent
commit
df745ac35c
  1. 4
      docker/golang.Dockerfile
  2. 2
      src/domains/app/app.go
  3. 6
      src/internal/rest/app.go
  4. 27
      src/services/app.go
  5. 21
      src/validations/app_validation.go
  6. 46
      src/validations/app_validation_test.go

4
docker/golang.Dockerfile

@ -1,7 +1,7 @@
############################ ############################
# STEP 1 build executable binary # STEP 1 build executable binary
############################ ############################
FROM golang:1.21.5-alpine3.19 AS builder
FROM golang:1.22.5-alpine3.20 AS builder
RUN apk update && apk add --no-cache gcc musl-dev gcompat RUN apk update && apk add --no-cache gcc musl-dev gcompat
WORKDIR /whatsapp WORKDIR /whatsapp
COPY ./src . COPY ./src .
@ -14,7 +14,7 @@ RUN go build -o /app/whatsapp
############################# #############################
## STEP 2 build a smaller image ## STEP 2 build a smaller image
############################# #############################
FROM alpine:3.19
FROM alpine:3.20
RUN apk update && apk add --no-cache ffmpeg RUN apk update && apk add --no-cache ffmpeg
WORKDIR /app WORKDIR /app
# Copy compiled from builder. # Copy compiled from builder.

2
src/domains/app/app.go

@ -7,7 +7,7 @@ import (
type IAppService interface { type IAppService interface {
Login(ctx context.Context) (response LoginResponse, err error) Login(ctx context.Context) (response LoginResponse, err error)
LoginWithCode(ctx context.Context, phoneNumber string) (err error)
LoginWithCode(ctx context.Context, phoneNumber string) (loginCode string, err error)
Logout(ctx context.Context) (err error) Logout(ctx context.Context) (err error)
Reconnect(ctx context.Context) (err error) Reconnect(ctx context.Context) (err error)
FirstDevice(ctx context.Context) (response DevicesResponse, err error) FirstDevice(ctx context.Context) (response DevicesResponse, err error)

6
src/internal/rest/app.go

@ -38,14 +38,16 @@ func (handler *App) Login(c *fiber.Ctx) error {
} }
func (handler *App) LoginWithCode(c *fiber.Ctx) error { func (handler *App) LoginWithCode(c *fiber.Ctx) error {
err := handler.Service.LoginWithCode(c.UserContext(), c.Query("phone"))
loginCode, err := handler.Service.LoginWithCode(c.UserContext(), c.Query("phone"))
utils.PanicIfNeeded(err) utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{ return c.JSON(utils.ResponseData{
Status: 200, Status: 200,
Code: "SUCCESS", Code: "SUCCESS",
Message: "Login with code success", Message: "Login with code success",
Results: nil,
Results: map[string]any{
"login_code": loginCode,
},
}) })
} }

27
src/services/app.go

@ -7,6 +7,8 @@ import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/config"
domainApp "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/app" domainApp "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/app"
pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error"
"github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp"
"github.com/aldinokemal/go-whatsapp-web-multidevice/validations"
fiberUtils "github.com/gofiber/fiber/v2/utils" fiberUtils "github.com/gofiber/fiber/v2/utils"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/skip2/go-qrcode" "github.com/skip2/go-qrcode"
@ -90,15 +92,28 @@ func (service serviceApp) Login(_ context.Context) (response domainApp.LoginResp
return response, nil return response, nil
} }
func (service serviceApp) LoginWithCode(ctx context.Context, phoneNumber string) (err error) {
phone, err := service.WaCli.PairPhone(phoneNumber, true, whatsmeow.PairClientChrome, "Chrome (Linux)")
if err != nil {
return err
func (service serviceApp) LoginWithCode(ctx context.Context, phoneNumber string) (loginCode string, err error) {
if err = validations.ValidateLoginWithCode(ctx, phoneNumber); err != nil {
logrus.Errorf("Error when validate login with code: %s", err.Error())
return loginCode, err
}
// detect is already logged in
if service.WaCli.IsLoggedIn() {
return loginCode, pkgError.ErrAlreadyLoggedIn
} }
logrus.Info("Phone: ", phone)
// check if on whatsapp
if exist := whatsapp.IsOnWhatsapp(service.WaCli, phoneNumber+"@s.whatsapp.net"); !exist {
return loginCode, pkgError.InvalidJID(fmt.Sprintf("Phone %s is not on whatsapp", phoneNumber))
}
loginCode, err = service.WaCli.PairPhone(phoneNumber, true, whatsmeow.PairClientChrome, "Chrome")
if err != nil {
return loginCode, err
}
return nil
return loginCode, nil
} }
func (service serviceApp) Logout(_ context.Context) (err error) { func (service serviceApp) Logout(_ context.Context) (err error) {

21
src/validations/app_validation.go

@ -0,0 +1,21 @@
package validations
import (
"context"
"fmt"
pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error"
validation "github.com/go-ozzo/ozzo-validation/v4"
"regexp"
)
func ValidateLoginWithCode(ctx context.Context, phoneNumber string) error {
// Combine validations using a single ValidateWithContext call
err := validation.ValidateWithContext(ctx, &phoneNumber,
validation.Required,
validation.Match(regexp.MustCompile(`^\+?[0-9]{1,15}$`)),
)
if err != nil {
return pkgError.ValidationError(fmt.Sprintf("phone_number(%s): %s", phoneNumber, err.Error()))
}
return nil
}

46
src/validations/app_validation_test.go

@ -0,0 +1,46 @@
package validations
import (
"context"
"testing"
)
func TestValidateLoginWithCode(t *testing.T) {
type args struct {
phoneNumber string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Phone with +",
args: args{phoneNumber: "+6281234567890"},
wantErr: false,
},
{
name: "Phone without +",
args: args{phoneNumber: "621234567890"},
wantErr: false,
},
{
name: "Phone with 0",
args: args{phoneNumber: "081234567890"},
wantErr: false,
},
{
name: "Phone contains alphabet",
args: args{phoneNumber: "+6281234567890a"},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := ValidateLoginWithCode(context.Background(), tt.args.phoneNumber); (err != nil) != tt.wantErr {
t.Errorf("ValidateLoginWithCode() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
Loading…
Cancel
Save