Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Abalasky tests for events handler #5

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea
vendor
my-api-key.txt
.vscode
Empty file added Changelog.md
Empty file.
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ require (
)

require (
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.3.0 // indirect
github.com/gorilla/websocket v1.4.1 // indirect
github.com/golang/protobuf v1.5.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.1.0 // indirect
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 // indirect
go.mau.fi/whatsmeow v0.0.0-20220302184339-7959f8e0ce83 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
17 changes: 17 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk=
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
github.com/Rhymen/go-whatsapp v0.1.1 h1:OK+bCugQcr2YjyYKeDzULqCtM50TPUFM6LvQtszKfcw=
Expand All @@ -15,9 +17,14 @@ github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
Expand All @@ -38,6 +45,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I=
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg=
go.mau.fi/whatsmeow v0.0.0-20220302184339-7959f8e0ce83 h1:MCwMGrfgzzIzunbAnb3CJ6DJqvll2gwcOZScvwmkYzg=
go.mau.fi/whatsmeow v0.0.0-20220302184339-7959f8e0ce83/go.mod h1:NNI4Ah/B27mfQNChJMD1iSO8+HS+fQ4WqNuQ8Mh2/XI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
Expand All @@ -49,6 +60,8 @@ golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -75,8 +88,12 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
35 changes: 28 additions & 7 deletions internal/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ const TextMessageFmt = "From: %s [jid: %s] \n= = = = = = = = = = = =\nMessage: %
type EventType string

const (
StartEventType EventType = "start"
LoginEventType EventType = "login"
LogoutEventType EventType = "logout"
HelpEventType EventType = "help"
TextMessageEventType EventType = "text_message" // whatsapp only
ReplyEventType EventType = "reply" // telegram only
DisconnectEventType EventType = "disconnect_event"
StartEventType EventType = "start"
LoginEventType EventType = "login"
LogoutEventType EventType = "logout"
HelpEventType EventType = "help"
TextMessageEventType EventType = "text_message" // whatsapp only
ImageMessageEventType EventType = "text_message" // whatsapp only
ReplyEventType EventType = "reply" // telegram only
DisconnectEventType EventType = "disconnect_event"
)

// Event represents a generic event API.
Expand Down Expand Up @@ -93,6 +94,25 @@ func (te *TextMessageEvent) Type() EventType {
return TextMessageEventType
}

// ImageMessageEvent represents an incoming image message
type ImageMessageEvent struct {
// ChatID is telegram bot chat identifier.
ChatID int64

// WhatsappRemoteJid is a whatsapp client identifier that sent the message.
WhatsappRemoteJid string

// WhatsappSenderName is a whatsapp client's name that sent the message.
WhatsappSenderName string

// Text is a text message body.
ImageBytes []byte
}

func (te *ImageMessageEvent) Type() EventType {
return ImageMessageEventType
}

// ReplyEvent represents a message reply event.
type ReplyEvent struct {
// ChatID is telegram bot chat identifier.
Expand Down Expand Up @@ -130,6 +150,7 @@ type EventsHandler interface {
HandleHelpEvent(*HelpEvent) error
HandleRepeatedLoginEvent(*LoginEvent) error
HandleTextMessageEvent(*TextMessageEvent) error
HandleImageMessageEvent(*ImageMessageEvent) error
HandleReplyEvent(*ReplyEvent) error
HandleDisconnectEvent(*DisconnectEvent) error
IsLoggedIn() bool
Expand Down
26 changes: 26 additions & 0 deletions internal/handler/events_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,32 @@ func (eh *EventsHandler) HandleTextMessageEvent(event *domain.TextMessageEvent)
return nil
}

// HandleImageMessageEvent method handles image message event.
func (eh *EventsHandler) HandleImageMessageEvent(event *domain.ImageMessageEvent) error {

eh.log.Debug("handle image message event",
zap.String("remote_jid", event.WhatsappRemoteJid))

imageReader := tgbotapi.FileReader{
Name: "ImageMessage",
Reader: bytes.NewReader(event.ImageBytes),
Size: int64(len(event.ImageBytes)),
}

photo := tgbotapi.NewPhotoUpload(eh.chatID, imageReader)
if _, err := eh.telegramAPI.Send(photo); err != nil {
eh.log.Error("failed to send QR-code", zap.Error(err))

return fmt.Errorf("failed to send image message chat_id=%d: %w",
event.ChatID,
err)
}

eh.log.Debug("Image message from whatsapp has been forwarded")

return nil
}

// HandleReplyEvent method handles reply event.
func (eh *EventsHandler) HandleReplyEvent(event *domain.ReplyEvent) error {
eh.log.Debug("reply to a message",
Expand Down
39 changes: 38 additions & 1 deletion internal/handler/events_handler_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
package handler_test

import "testing"
import (
"testing"

"github.com/dstdfx/twbridge/internal/domain"
"github.com/dstdfx/twbridge/internal/handler"
"go.uber.org/zap"
)

func TestEventsHandler(t *testing.T) {

testChatID := int64(123)
eventsHandler:= handler.NewEventsHandler(zap.NewNop(), &handler.Opts{
ChatID: testChatID,
})


t.Run("handle start event", func(t *testing.T) {

})
Expand All @@ -13,6 +26,30 @@ func TestEventsHandler(t *testing.T) {

t.Run("handle reply event", func(t *testing.T) {

type ReplyEvent struct {
// ChatID is telegram bot chat identifier.
ChatID int64

// FromUser is a telegram username of the client that interacts with the bot.
FromUser string

// Reply is a reply text message body.
Reply string

// RemoteJid is a whatsapp user identifier.
RemoteJid string
}

//Mock reply event
replyEvent := domain.ReplyEvent{
ChatID: testChatID,
FromUser: "User1",
Reply: "User2",
RemoteJid: "123",
}

eventsHandler.HandleReplyEvent(e); err != nil {

})

t.Run("handle text message event", func(t *testing.T) {
Expand Down
14 changes: 14 additions & 0 deletions internal/handler/mocks/events_handler_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/manager/clients_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (mgr *Manager) Run(ctx context.Context) {
case *domain.StartEvent:
var eventsHandler domain.EventsHandler

// Check if the client already has an events provider
// Check if the client already has an events handler
eventsHandler, ok := mgr.eventHandlers[e.ChatID]
if !ok {
// Create events handler for new client and handle event
Expand Down
40 changes: 40 additions & 0 deletions internal/whatsapp/events_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,43 @@ func (wh *EventsProvider) HandleTextMessage(message whatsapp.TextMessage) {
ChatID: wh.chatID,
}
}

// HandleTextMessage method is called when new image message is received.
func (wh *EventsProvider) HandleImageMessage(message whatsapp.ImageMessage) {
if message.Info.Timestamp < uint64(wh.startAt) || message.Info.FromMe {
return
}

wh.log.Debug("got text message",
zap.Bool("from_me", message.Info.FromMe),
zap.Int("status", int(message.Info.Status)),
zap.String("push_name", message.Info.PushName),
zap.Uint64("timestamp", message.Info.Timestamp),
zap.String("remote_jid", message.Info.RemoteJid),
zap.String("sender_jid", message.Info.SenderJid))

// Get the contact name from the contacts store
var contactName string
contacts := wh.whatsappClient.GetContacts()
contact, ok := contacts[message.Info.RemoteJid]
if !ok {
contactName = "<unknown>"
} else {
contactName = contact.Name
}

//Download media data
mediaData, err := message.Download()
if err != nil {
return
}

//Write event to channel
wh.outgoingEvents <- &domain.ImageMessageEvent{
WhatsappRemoteJid: message.Info.RemoteJid,
WhatsappSenderName: contactName,
ChatID: wh.chatID,
ImageBytes: mediaData,
}

}
Binary file added twbridge
Binary file not shown.