first webhook processor, fix errors
This commit is contained in:
parent
0e2cc70a09
commit
1e6407adfe
@ -1,10 +1,10 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/logger"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/logger"
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
@ -55,8 +55,8 @@ func (a *App) Conf() *config.Config {
|
|||||||
return a.Config
|
return a.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) DB() *db.Repositories {
|
func (a *App) DB() fsmcontract.Repositories {
|
||||||
return a.Repositories
|
return &DBWrapper{a.Repositories}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Localizer(lang string) locale.Localizer {
|
func (a *App) Localizer(lang string) locale.Localizer {
|
||||||
@ -122,7 +122,16 @@ func (a *App) longPoll() error {
|
|||||||
}
|
}
|
||||||
defer a.Telegram.StopLongPolling()
|
defer a.Telegram.StopLongPolling()
|
||||||
for update := range updates {
|
for update := range updates {
|
||||||
fmt.Printf("Update: %+v\n", update)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
a.Logger.Errorf("recovered from panic inside the handler: %v", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := a.handler(update).Handle(update); err != nil {
|
||||||
|
a.Logger.Errorf("error while handling the update: %s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
18
internal/app/db_wrapper.go
Normal file
18
internal/app/db_wrapper.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DBWrapper struct {
|
||||||
|
r *db.Repositories
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *DBWrapper) ForUser() fsmcontract.UserRepository {
|
||||||
|
return w.r.User
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *DBWrapper) ForChat() fsmcontract.ChatRepository {
|
||||||
|
return w.r.Chat
|
||||||
|
}
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
type Chat struct {
|
type Chat struct {
|
||||||
ID uint64 `gorm:"primaryKey; autoIncrement" json:"id"`
|
ID uint64 `gorm:"primaryKey; autoIncrement" json:"id"`
|
||||||
TelegramID uint64 `gorm:"column:telegram_id; not null" json:"telegramId"`
|
TelegramID int64 `gorm:"column:telegram_id; not null" json:"telegramId"`
|
||||||
UserID uint64 `gorm:"column:user_id; not null"`
|
UserID int64 `gorm:"column:user_id; not null"`
|
||||||
Members ChatMembers `gorm:"column:members; not null" json:"members"`
|
Members ChatMembers `gorm:"column:members; not null" json:"members"`
|
||||||
Integrations []Integration `gorm:"foreignKey:ChatID" json:"integrations"`
|
Integrations []Integration `gorm:"foreignKey:ChatID" json:"integrations"`
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ func (Chat) TableName() string {
|
|||||||
return "chat"
|
return "chat"
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatMembers []uint64
|
type ChatMembers []int64
|
||||||
|
|
||||||
func (cm *ChatMembers) Scan(value interface{}) error {
|
func (cm *ChatMembers) Scan(value interface{}) error {
|
||||||
switch v := value.(type) {
|
switch v := value.(type) {
|
||||||
@ -41,8 +41,12 @@ func (cm *ChatMembers) Scan(value interface{}) error {
|
|||||||
|
|
||||||
func (cm ChatMembers) Value() (driver.Value, error) {
|
func (cm ChatMembers) Value() (driver.Value, error) {
|
||||||
if cm == nil {
|
if cm == nil {
|
||||||
return nil, nil
|
return "[]", nil
|
||||||
}
|
}
|
||||||
jsonData, err := json.Marshal(cm)
|
jsonData, err := json.Marshal(cm)
|
||||||
return string(jsonData), err
|
return string(jsonData), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ChatMembers) GormDataType() string {
|
||||||
|
return "json"
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
type Integration struct {
|
type Integration struct {
|
||||||
ID uint64 `gorm:"primaryKey; autoIncrement;"`
|
ID uint64 `gorm:"primaryKey; autoIncrement;"`
|
||||||
Type IntegrationType `gorm:"column:type; not null"`
|
Type IntegrationType `gorm:"column:type; not null"`
|
||||||
ChatID uint64 `gorm:"column:chat_id; not null"`
|
ChatID int64 `gorm:"column:chat_id; not null"`
|
||||||
Params datatypes.JSONMap `gorm:"column:params; not null"`
|
Params datatypes.JSONMap `gorm:"column:params; not null"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,5 +60,9 @@ func (it IntegrationType) Value() (driver.Value, error) {
|
|||||||
if ok {
|
if ok {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
return "", errors.New("invalid IntegrationType")
|
return InvalidIntegration, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (IntegrationType) GormDataType() string {
|
||||||
|
return "varchar(24)"
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package model
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uint64 `gorm:"primary_key;auto_increment" json:"id"`
|
ID uint64 `gorm:"primary_key;auto_increment" json:"id"`
|
||||||
TelegramID uint64 `gorm:"not null" json:"telegram_id"`
|
TelegramID int64 `gorm:"not null" json:"telegram_id"`
|
||||||
Chats []Chat `gorm:"foreignKey:UserID" json:"chats"`
|
Chats []Chat `gorm:"foreignKey:UserID" json:"chats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,17 +15,17 @@ func NewChat(db *gorm.DB) *Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chat) ByID(id uint64) (*model.Chat, error) {
|
func (c *Chat) ByID(id uint64) (*model.Chat, error) {
|
||||||
var chat *model.Chat
|
var chat model.Chat
|
||||||
if err := c.db.First(&chat, id).Error; err != nil {
|
if err := c.db.Model(&chat).First(&chat, id).Error; err != nil {
|
||||||
return nil, util.HandleRecordNotFound(err)
|
return nil, util.HandleRecordNotFound(err)
|
||||||
}
|
}
|
||||||
return chat, nil
|
return &chat, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chat) ByIDWithIntegrations(id uint64) (*model.Chat, error) {
|
func (c *Chat) ByIDWithIntegrations(id uint64) (*model.Chat, error) {
|
||||||
var chat *model.Chat
|
var chat model.Chat
|
||||||
if err := c.db.Preload("Integrations").First(&chat, id).Error; err != nil {
|
if err := c.db.Model(&chat).Preload("Integrations").First(&chat, id).Error; err != nil {
|
||||||
return nil, util.HandleRecordNotFound(err)
|
return nil, util.HandleRecordNotFound(err)
|
||||||
}
|
}
|
||||||
return chat, nil
|
return &chat, nil
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,29 @@ func NewUser(db *gorm.DB) *User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) ByID(id uint64) (*model.User, error) {
|
func (u *User) ByID(id uint64) (*model.User, error) {
|
||||||
var user *model.User
|
var user model.User
|
||||||
if err := u.db.First(&user, id).Error; err != nil {
|
if err := u.db.Model(&user).First(&user, id).Error; err != nil {
|
||||||
return nil, util.HandleRecordNotFound(err)
|
return nil, util.HandleRecordNotFound(err)
|
||||||
}
|
}
|
||||||
return user, nil
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) ByTelegramID(id int64) (*model.User, error) {
|
||||||
|
var user model.User
|
||||||
|
if err := u.db.Model(model.User{TelegramID: id}).First(&user).Error; err != nil {
|
||||||
|
return nil, util.HandleRecordNotFound(err)
|
||||||
|
}
|
||||||
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) ByIDWithChats(id uint64) (*model.User, error) {
|
func (u *User) ByIDWithChats(id uint64) (*model.User, error) {
|
||||||
var user *model.User
|
var user model.User
|
||||||
if err := u.db.Preload("Chats").First(&user, id).Error; err != nil {
|
if err := u.db.Model(&user).Preload("Chats").First(&user, id).Error; err != nil {
|
||||||
return nil, util.HandleRecordNotFound(err)
|
return nil, util.HandleRecordNotFound(err)
|
||||||
}
|
}
|
||||||
return user, nil
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) Save(user *model.User) error {
|
||||||
|
return u.db.Model(&model.User{}).Save(user).Error
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChatMemberUpdatedHandler struct {
|
type ChatMemberUpdatedHandler struct {
|
||||||
app App
|
app fsmcontract.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChatMemberUpdatedHandler(app App) *ChatMemberUpdatedHandler {
|
func NewChatMemberUpdatedHandler(app fsmcontract.App) *ChatMemberUpdatedHandler {
|
||||||
return &ChatMemberUpdatedHandler{app: app}
|
return &ChatMemberUpdatedHandler{app: app}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package fsmcontract
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
|
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -17,6 +16,6 @@ type App interface {
|
|||||||
Log() *zap.SugaredLogger
|
Log() *zap.SugaredLogger
|
||||||
TG() *telego.Bot
|
TG() *telego.Bot
|
||||||
Conf() *config.Config
|
Conf() *config.Config
|
||||||
DB() *db.Repositories
|
DB() Repositories
|
||||||
Localizer(string) locale.Localizer
|
Localizer(string) locale.Localizer
|
||||||
}
|
}
|
||||||
|
15
internal/handler/fsm/fsmcontract/db.go
Normal file
15
internal/handler/fsm/fsmcontract/db.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package fsmcontract
|
||||||
|
|
||||||
|
import "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model"
|
||||||
|
|
||||||
|
type Repositories interface {
|
||||||
|
ForUser() UserRepository
|
||||||
|
ForChat() ChatRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserRepository interface {
|
||||||
|
ByTelegramID(id int64) (*model.User, error)
|
||||||
|
Save(user *model.User) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatRepository interface{}
|
@ -24,14 +24,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Payload struct {
|
type Payload struct {
|
||||||
User uint64 `json:"u,omitempty"`
|
User int64 `json:"u,omitempty"`
|
||||||
Chat uint64 `json:"c,omitempty"`
|
Chat int64 `json:"c,omitempty"`
|
||||||
Action PayloadAction `json:"a"`
|
Action PayloadAction `json:"a"`
|
||||||
Data json.RawMessage `json:"d,omitempty"`
|
Data json.RawMessage `json:"d,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Member struct {
|
type Member struct {
|
||||||
ID uint64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ type Answer struct {
|
|||||||
Result bool `json:"r"`
|
Result bool `json:"r"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNextPageMembersPayload(userID, chatID uint64) *Payload {
|
func NewNextPageMembersPayload(userID, chatID int64) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionNext,
|
Action: PayloadActionNext,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -52,7 +52,7 @@ func NewNextPageMembersPayload(userID, chatID uint64) *Payload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPrevPageMembersPayload(userID, chatID uint64) *Payload {
|
func NewPrevPageMembersPayload(userID, chatID int64) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionPrevious,
|
Action: PayloadActionPrevious,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -60,7 +60,7 @@ func NewPrevPageMembersPayload(userID, chatID uint64) *Payload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAddMemberPayload(userID, chatID, memberID uint64, memberName string) *Payload {
|
func NewAddMemberPayload(userID, chatID, memberID int64, memberName string) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionAddMember,
|
Action: PayloadActionAddMember,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -69,7 +69,7 @@ func NewAddMemberPayload(userID, chatID, memberID uint64, memberName string) *Pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRemoveMemberPayload(userID, chatID, memberID uint64, memberName string) *Payload {
|
func NewRemoveMemberPayload(userID, chatID, memberID int64, memberName string) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionRemoveMember,
|
Action: PayloadActionRemoveMember,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -78,7 +78,7 @@ func NewRemoveMemberPayload(userID, chatID, memberID uint64, memberName string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVotePayload(chatID uint64, vote float32) *Payload {
|
func NewVotePayload(chatID int64, vote float32) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionVote,
|
Action: PayloadActionVote,
|
||||||
Chat: chatID,
|
Chat: chatID,
|
||||||
@ -86,7 +86,7 @@ func NewVotePayload(chatID uint64, vote float32) *Payload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfirmMembersPayload(userID uint64, chatID uint64) *Payload {
|
func NewConfirmMembersPayload(userID int64, chatID int64) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionYesNo,
|
Action: PayloadActionYesNo,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -95,7 +95,7 @@ func NewConfirmMembersPayload(userID uint64, chatID uint64) *Payload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRedmineQuestionPayload(userID uint64, chatID uint64, isYes bool) *Payload {
|
func NewRedmineQuestionPayload(userID int64, chatID int64, isYes bool) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionYesNo,
|
Action: PayloadActionYesNo,
|
||||||
User: userID,
|
User: userID,
|
||||||
@ -104,7 +104,7 @@ func NewRedmineQuestionPayload(userID uint64, chatID uint64, isYes bool) *Payloa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRedmineHoursQuestionPayload(userID uint64, chatID uint64, isYes bool) *Payload {
|
func NewRedmineHoursQuestionPayload(userID int64, chatID int64, isYes bool) *Payload {
|
||||||
return &Payload{
|
return &Payload{
|
||||||
Action: PayloadActionYesNo,
|
Action: PayloadActionYesNo,
|
||||||
User: userID,
|
User: userID,
|
||||||
|
@ -25,11 +25,11 @@ type PollState struct {
|
|||||||
Result PollResult
|
Result PollResult
|
||||||
}
|
}
|
||||||
|
|
||||||
var Polls otter.Cache[uint64, PollState]
|
var Polls otter.Cache[int64, PollState]
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cache, err := otter.MustBuilder[uint64, PollState](10_000).
|
cache, err := otter.MustBuilder[int64, PollState](10_000).
|
||||||
Cost(func(key uint64, value PollState) uint32 {
|
Cost(func(key int64, value PollState) uint32 {
|
||||||
return 1
|
return 1
|
||||||
}).
|
}).
|
||||||
WithTTL(time.Hour * 24 * 7).
|
WithTTL(time.Hour * 24 * 7).
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
userMachines = newStore[uint64, fsmcontract.Machine]()
|
userMachines = newStore[int64, fsmcontract.Machine]()
|
||||||
pollMachines = newStore[uint64, fsmcontract.Machine]()
|
pollMachines = newStore[int64, fsmcontract.Machine]()
|
||||||
)
|
)
|
||||||
|
|
||||||
type store[K comparable, V any] struct {
|
type store[K comparable, V any] struct {
|
||||||
@ -32,7 +32,7 @@ func (s *store[K, V]) Load(k K) (v V, ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ForUser(id uint64) fsmcontract.Machine {
|
func ForUser(id int64) fsmcontract.Machine {
|
||||||
val, ok := userMachines.Load(id)
|
val, ok := userMachines.Load(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
machine := newUserMachine()
|
machine := newUserMachine()
|
||||||
@ -42,7 +42,7 @@ func ForUser(id uint64) fsmcontract.Machine {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
func ForPoll(id uint64) fsmcontract.Machine {
|
func ForPoll(id int64) fsmcontract.Machine {
|
||||||
val, ok := pollMachines.Load(id)
|
val, ok := pollMachines.Load(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
machine := newPollMachine()
|
machine := newPollMachine()
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
|
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
|
|
||||||
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Type uint8
|
type Type uint8
|
||||||
@ -16,14 +12,6 @@ const (
|
|||||||
ChatMemberUpdated
|
ChatMemberUpdated
|
||||||
)
|
)
|
||||||
|
|
||||||
type App interface {
|
|
||||||
Log() *zap.SugaredLogger
|
|
||||||
TG() *telego.Bot
|
|
||||||
Conf() *config.Config
|
|
||||||
DB() *db.Repositories
|
|
||||||
Localizer(string) locale.Localizer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
Handle(update telego.Update) error
|
Handle(update telego.Update) error
|
||||||
}
|
}
|
||||||
|
28
internal/handler/iface/base.go
Normal file
28
internal/handler/iface/base.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package iface
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Base struct {
|
||||||
|
App fsmcontract.App
|
||||||
|
UserID int64
|
||||||
|
ChatID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBase(app fsmcontract.App, userID int64, chatID int64) Base {
|
||||||
|
return Base{app, userID, chatID}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Base) Localizer(lang string) locale.Localizer {
|
||||||
|
if len(lang) > 2 {
|
||||||
|
lang = lang[:2]
|
||||||
|
}
|
||||||
|
switch lang {
|
||||||
|
case "en", "ru":
|
||||||
|
return b.App.Localizer(lang)
|
||||||
|
default:
|
||||||
|
return b.App.Localizer("en")
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,35 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/util"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/wizard"
|
||||||
"github.com/mymmrac/telego"
|
"github.com/mymmrac/telego"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageHandler struct {
|
type MessageHandler struct {
|
||||||
app App
|
app fsmcontract.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessageHandler(app App) Handler {
|
func NewMessageHandler(app fsmcontract.App) Handler {
|
||||||
return &MessageHandler{app: app}
|
return &MessageHandler{app: app}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MessageHandler) Handle(telego.Update) error {
|
func (h *MessageHandler) Handle(wh telego.Update) error {
|
||||||
// TODO implement me
|
if wh.Message != nil {
|
||||||
panic("implement me")
|
if wh.Message.From != nil &&
|
||||||
|
wh.Message.Chat.Type == telego.ChatTypePrivate &&
|
||||||
|
util.MatchCommand("start", wh.Message) {
|
||||||
|
return wizard.NewRegister(h.app, wh.Message.From.ID, wh.Message.Chat.ID).Handle(wh)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove debug statement below.
|
||||||
|
h.app.Log().Debugf("New Message: %s", func(msg *telego.Message) string {
|
||||||
|
data, _ := json.Marshal(msg)
|
||||||
|
return string(data)
|
||||||
|
}(wh.Message))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
10
internal/handler/util/command.go
Normal file
10
internal/handler/util/command.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mymmrac/telego"
|
||||||
|
th "github.com/mymmrac/telego/telegohandler"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MatchCommand(command string, msg *telego.Message) bool {
|
||||||
|
return th.CommandEqual(command)(telego.Update{Message: msg})
|
||||||
|
}
|
54
internal/handler/wizard/register.go
Normal file
54
internal/handler/wizard/register.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package wizard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||||||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface"
|
||||||
|
"github.com/mymmrac/telego"
|
||||||
|
tu "github.com/mymmrac/telego/telegoutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Register struct {
|
||||||
|
iface.Base
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRegister(app fsmcontract.App, userID, chatID int64) *Register {
|
||||||
|
return &Register{iface.NewBase(app, userID, chatID)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Register) Handle(wh telego.Update) error {
|
||||||
|
loc := h.Localizer(wh.Message.From.LanguageCode)
|
||||||
|
userRepo := h.App.DB().ForUser()
|
||||||
|
user, err := userRepo.ByTelegramID(wh.Message.From.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if user != nil && user.ID > 0 {
|
||||||
|
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
|
||||||
|
ChatID: tu.ID(wh.Message.Chat.ID),
|
||||||
|
Text: loc.Message("welcome"),
|
||||||
|
ParseMode: telego.ModeMarkdown,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = userRepo.Save(&model.User{
|
||||||
|
TelegramID: wh.Message.From.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
_, _ = h.App.TG().SendMessage(&telego.SendMessageParams{
|
||||||
|
ChatID: tu.ID(wh.Message.Chat.ID),
|
||||||
|
Text: loc.Message("internal_error"),
|
||||||
|
ParseMode: telego.ModeMarkdown,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = h.App.TG().SendMessage(&telego.SendMessageParams{
|
||||||
|
ChatID: tu.ID(wh.Message.Chat.ID),
|
||||||
|
Text: loc.Message("welcome"),
|
||||||
|
ParseMode: telego.ModeMarkdown,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
welcome: "👋 Hello! This bot allows you to conduct Scrum Poker directly in a Telegram chat and pass results to issues tied to a Redmine instance. To start, add the bot to the chat where you want to conduct poker. After this, you can continue with the setup."
|
welcome: "👋 Hello! This bot allows you to conduct Scrum Poker directly in a Telegram chat and pass results to issues tied to a Redmine instance. To start, add the bot to the chat where you want to conduct poker. After this, you can continue with the setup."
|
||||||
|
internal_error: "❌ Internal error, try again later."
|
||||||
bot_was_added: "Great, the bot has been added to the chat \"{{.Name}}\". Choose chat members who will participate in the poker."
|
bot_was_added: "Great, the bot has been added to the chat \"{{.Name}}\". Choose chat members who will participate in the poker."
|
||||||
previous: "◀️ Back"
|
previous: "◀️ Back"
|
||||||
next: "Next ▶️"
|
next: "Next ▶️"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
welcome: "👋 Привет! Этот бот позволяет проводить Scrum Poker прямо в чате Telegram и передавать результаты в задачи в привязанном Redmine. Для начала добавьте бота в чат, в котором вы хотите проводить poker. После этого вы сможете продолжить настройку."
|
welcome: "👋 Привет! Этот бот позволяет проводить Scrum Poker прямо в чате Telegram и передавать результаты в задачи в привязанном Redmine. Для начала добавьте бота в чат, в котором вы хотите проводить poker. После этого вы сможете продолжить настройку."
|
||||||
|
internal_error: "❌ Внутренняя ошибка, попробуйте попытку позже."
|
||||||
bot_was_added: "Отлично, бот был добавлен в чат \"{{.Name}}\". Выберите участников чата, которые будут участвовать в покере."
|
bot_was_added: "Отлично, бот был добавлен в чат \"{{.Name}}\". Выберите участников чата, которые будут участвовать в покере."
|
||||||
previous: "◀️ Назад"
|
previous: "◀️ Назад"
|
||||||
next: "Вперед ▶️"
|
next: "Вперед ▶️"
|
||||||
|
Loading…
Reference in New Issue
Block a user