1
0
mirror of https://github.com/nikoksr/notify.git synced 2024-11-28 08:39:13 +02:00

refactor(service): Separate out login into LoginWithQRCode and LoginWithSessionCredentials

This commit is contained in:
checkaayush 2021-02-17 13:11:43 +05:30
parent 3f19caef1a
commit fe2d0ee118
5 changed files with 104 additions and 17 deletions

View File

@ -8,7 +8,17 @@ You will need a registered WhatsApp phone number to be used as source for sendin
## Usage
In the current implementation, authentication requires scanning QR code from terminal using a registered WhatsApp device. Please refer [Login (go-whatsapp)](https://github.com/Rhymen/go-whatsapp#login) and [sigalor/whatsapp-web-reveng](https://github.com/sigalor/whatsapp-web-reveng) for more details.
In the current implementation, authentication is implemented using 2 ways:
1. Scanning QR code from terminal using a registered WhatsApp device.
- Go to WhatsApp on your device.
- Click on the ellipsis icon (3 vertical dots) on top right, then click on "WhatsApp Web".
- Click on the "+" icon and scan the QR code from terminal.
> Refer: [Login (go-whatsapp)](https://github.com/Rhymen/go-whatsapp#login) and [sigalor/whatsapp-web-reveng](https://github.com/sigalor/whatsapp-web-reveng) for more details.
2. Providing the Session credentials explicitly.
```go
package main
@ -26,6 +36,11 @@ func main() {
log.Fatalf("whatsapp.New() failed: %s", err.Error())
}
err = whatsappSvc.LoginWithQRCode()
if err != nil {
log.Fatalf("whatsappSvc.LoginWithQRCode() failed: %s", err.Error())
}
whatsappSvc.AddReceivers("Contact1")
notifier := notify.New()

View File

@ -18,6 +18,11 @@ Usage:
log.Fatalf("whatsapp.New() failed: %s", err.Error())
}
err = whatsappSvc.LoginWithQRCode()
if err != nil {
log.Fatalf("whatsappSvc.LoginWithQRCode() failed: %s", err.Error())
}
whatsappSvc.AddReceivers("Contact1")
notifier := notify.New()

View File

@ -2,13 +2,58 @@
package whatsapp
import mock "github.com/stretchr/testify/mock"
import (
"github.com/Rhymen/go-whatsapp"
"github.com/stretchr/testify/mock"
)
// mockWhatsappClient is an autogenerated mock type for the whatsappClient type
type mockWhatsappClient struct {
mock.Mock
}
// Login provides a mock function with given fields: qrChan
func (_m *mockWhatsappClient) Login(qrChan chan<- string) (whatsapp.Session, error) {
ret := _m.Called(qrChan)
var r0 whatsapp.Session
if rf, ok := ret.Get(0).(func(chan<- string) whatsapp.Session); ok {
r0 = rf(qrChan)
} else {
r0 = ret.Get(0).(whatsapp.Session)
}
var r1 error
if rf, ok := ret.Get(1).(func(chan<- string) error); ok {
r1 = rf(qrChan)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// RestoreWithSession provides a mock function with given fields: session
func (_m *mockWhatsappClient) RestoreWithSession(session whatsapp.Session) (whatsapp.Session, error) {
ret := _m.Called(session)
var r0 whatsapp.Session
if rf, ok := ret.Get(0).(func(whatsapp.Session) whatsapp.Session); ok {
r0 = rf(session)
} else {
r0 = ret.Get(0).(whatsapp.Session)
}
var r1 error
if rf, ok := ret.Get(1).(func(whatsapp.Session) error); ok {
r1 = rf(session)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Send provides a mock function with given fields: msg
func (_m *mockWhatsappClient) Send(msg interface{}) (string, error) {
ret := _m.Called(msg)

View File

@ -7,17 +7,19 @@ import (
"time"
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
whatsapp "github.com/Rhymen/go-whatsapp"
"github.com/Rhymen/go-whatsapp"
"github.com/pkg/errors"
)
const (
loginWaitTimeSeconds = 3
clientTimeout = 5
qrLoginWaitTimeSeconds = 3
clientTimeout = 5
)
// whatsappClient abstracts go-whatsapp for writing unit tests
type whatsappClient interface {
Login(qrChan chan<- string) (whatsapp.Session, error)
RestoreWithSession(session whatsapp.Session) (whatsapp.Session, error)
Send(msg interface{}) (string, error)
}
@ -34,13 +36,6 @@ func New() (*Service, error) {
return nil, err
}
err = login(client)
if err != nil {
return nil, err
}
<-time.After(loginWaitTimeSeconds * time.Second)
s := &Service{
client: client,
contacts: []string{},
@ -48,12 +43,37 @@ func New() (*Service, error) {
return s, nil
}
// login helps with the WhatsApp authentication process.
// LoginWithSessionCredentials provides helper for authentication using whatsapp.Session credentials.
func (s *Service) LoginWithSessionCredentials(clientID, clientToken, serverToken, wid string, encKey, macKey []byte) error {
session := whatsapp.Session{
ClientId: clientID,
ClientToken: clientToken,
ServerToken: serverToken,
Wid: wid,
EncKey: encKey,
MacKey: macKey,
}
session, err := s.client.RestoreWithSession(session)
if err != nil {
return fmt.Errorf("restoring session failed: %v", err)
}
// Save the updated session for future use without login.
err = writeSession(&session)
if err != nil {
return fmt.Errorf("error saving session: %v", err)
}
return nil
}
// LoginWithQRCode provides helper for authentication using QR code on terminal.
// Refer: https://github.com/Rhymen/go-whatsapp#login for more information.
func login(client *whatsapp.Conn) error {
func (s *Service) LoginWithQRCode() error {
session, err := readSession()
if err == nil {
session, err = client.RestoreWithSession(session)
session, err = s.client.RestoreWithSession(session)
if err != nil {
return fmt.Errorf("restoring session failed: %v", err)
}
@ -65,7 +85,7 @@ func login(client *whatsapp.Conn) error {
terminal.Get(<-qr).Print()
}()
session, err = client.Login(qr)
session, err = s.client.Login(qr)
if err != nil {
return fmt.Errorf("error during login: %v", err)
}
@ -76,6 +96,8 @@ func login(client *whatsapp.Conn) error {
return fmt.Errorf("error saving session: %v", err)
}
<-time.After(qrLoginWaitTimeSeconds * time.Second)
return nil
}

View File

@ -3,7 +3,7 @@ package whatsapp
import (
"testing"
whatsapp "github.com/Rhymen/go-whatsapp"
"github.com/Rhymen/go-whatsapp"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)