add all bot
This commit is contained in:
parent
116f4041fa
commit
2889f35a3d
|
@ -5,6 +5,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger/telegram"
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger/telegram"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/storage"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/services/bot"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/services/bot/bot_all"
|
||||||
"git.3crabs.ru/VLADIMIR/butler/internal/services/listener"
|
"git.3crabs.ru/VLADIMIR/butler/internal/services/listener"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,7 +17,13 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
listenerService := listener.NewListener(messengerTelegram)
|
var storage storage.IStorage // TODO: init
|
||||||
|
listenerService := listener.NewListener(
|
||||||
|
messengerTelegram,
|
||||||
|
[]bot.IBot{
|
||||||
|
bot_all.NewBotAll(messengerTelegram, storage),
|
||||||
|
},
|
||||||
|
)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
listenerService.Run(ctx)
|
listenerService.Run(ctx)
|
||||||
}
|
}
|
||||||
|
|
10
go.mod
10
go.mod
|
@ -2,4 +2,12 @@ module git.3crabs.ru/VLADIMIR/butler
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect
|
require (
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
|
go.uber.org/mock v0.2.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/samber/lo v1.38.1 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||||
|
)
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -1,2 +1,8 @@
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
|
||||||
|
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||||
|
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||||
|
go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU=
|
||||||
|
go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM=
|
||||||
|
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
|
||||||
|
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package messenger
|
package messenger
|
||||||
|
|
||||||
|
//go:generate mockgen -source=$GOFILE -destination=mocks/$GOFILE -package=mocks
|
||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: interface.go
|
||||||
|
|
||||||
|
// Package mocks is a generated GoMock package.
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
messenger "git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockIMessenger is a mock of IMessenger interface.
|
||||||
|
type MockIMessenger struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockIMessengerMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockIMessengerMockRecorder is the mock recorder for MockIMessenger.
|
||||||
|
type MockIMessengerMockRecorder struct {
|
||||||
|
mock *MockIMessenger
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockIMessenger creates a new mock instance.
|
||||||
|
func NewMockIMessenger(ctrl *gomock.Controller) *MockIMessenger {
|
||||||
|
mock := &MockIMessenger{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockIMessengerMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockIMessenger) EXPECT() *MockIMessengerMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMessage mocks base method.
|
||||||
|
func (m *MockIMessenger) GetMessage(ctx context.Context) (*messenger.Message, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetMessage", ctx)
|
||||||
|
ret0, _ := ret[0].(*messenger.Message)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMessage indicates an expected call of GetMessage.
|
||||||
|
func (mr *MockIMessengerMockRecorder) GetMessage(ctx interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessage", reflect.TypeOf((*MockIMessenger)(nil).GetMessage), ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessage mocks base method.
|
||||||
|
func (m *MockIMessenger) SendMessage(ctx context.Context, msg *messenger.Message) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "SendMessage", ctx, msg)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessage indicates an expected call of SendMessage.
|
||||||
|
func (mr *MockIMessengerMockRecorder) SendMessage(ctx, msg interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockIMessenger)(nil).SendMessage), ctx, msg)
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
//go:generate mockgen -source=$GOFILE -destination=mocks/$GOFILE -package=mocks
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ChatID string
|
||||||
|
UserID string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IStorage interface {
|
||||||
|
UpsertUser(ctx context.Context, user User) error
|
||||||
|
GetAllUsersByChatID(ctx context.Context, chatID string) ([]User, error)
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: interface.go
|
||||||
|
|
||||||
|
// Package mocks is a generated GoMock package.
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
storage "git.3crabs.ru/VLADIMIR/butler/internal/modules/storage"
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockIStorage is a mock of IStorage interface.
|
||||||
|
type MockIStorage struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockIStorageMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockIStorageMockRecorder is the mock recorder for MockIStorage.
|
||||||
|
type MockIStorageMockRecorder struct {
|
||||||
|
mock *MockIStorage
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockIStorage creates a new mock instance.
|
||||||
|
func NewMockIStorage(ctrl *gomock.Controller) *MockIStorage {
|
||||||
|
mock := &MockIStorage{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockIStorageMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockIStorage) EXPECT() *MockIStorageMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllUsersByChatID mocks base method.
|
||||||
|
func (m *MockIStorage) GetAllUsersByChatID(ctx context.Context, chatID string) ([]storage.User, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetAllUsersByChatID", ctx, chatID)
|
||||||
|
ret0, _ := ret[0].([]storage.User)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllUsersByChatID indicates an expected call of GetAllUsersByChatID.
|
||||||
|
func (mr *MockIStorageMockRecorder) GetAllUsersByChatID(ctx, chatID interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllUsersByChatID", reflect.TypeOf((*MockIStorage)(nil).GetAllUsersByChatID), ctx, chatID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpsertUser mocks base method.
|
||||||
|
func (m *MockIStorage) UpsertUser(ctx context.Context, user storage.User) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "UpsertUser", ctx, user)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpsertUser indicates an expected call of UpsertUser.
|
||||||
|
func (mr *MockIStorageMockRecorder) UpsertUser(ctx, user interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertUser", reflect.TypeOf((*MockIStorage)(nil).UpsertUser), ctx, user)
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package bot_all
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
|
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/storage"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/services/bot"
|
||||||
|
)
|
||||||
|
|
||||||
|
type botAll struct {
|
||||||
|
messenger messenger.IMessenger
|
||||||
|
storage storage.IStorage
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBotAll(
|
||||||
|
messenger messenger.IMessenger,
|
||||||
|
storage storage.IStorage,
|
||||||
|
) bot.IBot {
|
||||||
|
return &botAll{
|
||||||
|
messenger: messenger,
|
||||||
|
storage: storage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bot *botAll) Process(ctx context.Context, msg messenger.Message) error {
|
||||||
|
if err := bot.storage.UpsertUser(ctx, storage.User{ChatID: msg.ChatID, UserID: msg.UserID}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !strings.Contains(msg.Text, "@all") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
users, err := bot.storage.GetAllUsersByChatID(ctx, msg.ChatID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
usernames := lo.Map(users, func(item storage.User, _ int) string {
|
||||||
|
return item.UserID
|
||||||
|
})
|
||||||
|
if len(usernames) > 0 {
|
||||||
|
bot.messenger.SendMessage(
|
||||||
|
ctx,
|
||||||
|
&messenger.Message{
|
||||||
|
ChatID: msg.ChatID,
|
||||||
|
Text: strings.Join(usernames, " "),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package bot_all
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"go.uber.org/mock/gomock"
|
||||||
|
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
||||||
|
messenger_mocks "git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger/mocks"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/storage"
|
||||||
|
storage_mocks "git.3crabs.ru/VLADIMIR/butler/internal/modules/storage/mocks"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_botAll_Process(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
messenger func(ctrl *gomock.Controller) messenger.IMessenger
|
||||||
|
storage func(ctrl *gomock.Controller) storage.IStorage
|
||||||
|
msg messenger.Message
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "hello message",
|
||||||
|
messenger: func(ctrl *gomock.Controller) messenger.IMessenger {
|
||||||
|
m := messenger_mocks.NewMockIMessenger(ctrl)
|
||||||
|
m.EXPECT().SendMessage(gomock.Any(), gomock.Any()).Times(0)
|
||||||
|
return m
|
||||||
|
},
|
||||||
|
storage: func(ctrl *gomock.Controller) storage.IStorage {
|
||||||
|
m := storage_mocks.NewMockIStorage(ctrl)
|
||||||
|
m.EXPECT().UpsertUser(gomock.Any(), storage.User{ChatID: "123", UserID: "username"}).Times(1)
|
||||||
|
m.EXPECT().GetAllUsersByChatID(gomock.Any(), gomock.Any()).Times(0)
|
||||||
|
return m
|
||||||
|
},
|
||||||
|
msg: messenger.Message{
|
||||||
|
ChatID: "123",
|
||||||
|
UserID: "username",
|
||||||
|
Text: "hello",
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
ctx := context.Background()
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
bot := &botAll{
|
||||||
|
messenger: tt.messenger(ctrl),
|
||||||
|
storage: tt.storage(ctrl),
|
||||||
|
}
|
||||||
|
if err := bot.Process(ctx, tt.msg); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("botAll.Process() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package bot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IBot interface {
|
||||||
|
Process(ctx context.Context, msg messenger.Message) error
|
||||||
|
}
|
|
@ -2,21 +2,25 @@ package listener
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"log"
|
||||||
|
|
||||||
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
"git.3crabs.ru/VLADIMIR/butler/internal/modules/messenger"
|
||||||
"git.3crabs.ru/VLADIMIR/butler/internal/services"
|
"git.3crabs.ru/VLADIMIR/butler/internal/services"
|
||||||
|
"git.3crabs.ru/VLADIMIR/butler/internal/services/bot"
|
||||||
)
|
)
|
||||||
|
|
||||||
type listenerService struct {
|
type listenerService struct {
|
||||||
messenger messenger.IMessenger
|
messenger messenger.IMessenger
|
||||||
|
bots []bot.IBot
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListener(
|
func NewListener(
|
||||||
messenger messenger.IMessenger,
|
messenger messenger.IMessenger,
|
||||||
|
bots []bot.IBot,
|
||||||
) services.IService {
|
) services.IService {
|
||||||
return &listenerService{
|
return &listenerService{
|
||||||
messenger: messenger,
|
messenger: messenger,
|
||||||
|
bots: bots,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +33,10 @@ func (s *listenerService) Run(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := s.messenger.SendMessage(ctx, msg); err != nil {
|
for b := range s.bots {
|
||||||
fmt.Println(err)
|
if err := b.Process(ctx, msg); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue