♻️ Refactored events and middlewares

close #9
This commit is contained in:
Maxim Lebedev 2019-10-16 20:16:44 +05:00
parent 17aa5037c9
commit db48dcc904
No known key found for this signature in database
GPG Key ID: F8978F46FF0FFA4F
25 changed files with 761 additions and 620 deletions

View File

@ -36,56 +36,59 @@ func init() {
}
var messageKeyToIndex = map[string]int{
"birthday__button_text-donate": 15,
"birthday__message_text": 14,
"callback__text_add-set": 2,
"callback__text_add-single": 0,
"callback__text_language": 10,
"callback__text_language-same": 8,
"callback__text_remove-set": 6,
"callback__text_remove-single": 4,
"help__text": 14,
"inline__found_switch-text": 12,
"inline__not-found_switch-text": 11,
"settings-command__text": 9,
"start__text": 13,
"help__text": 11,
"inline__found_switch-text": 9,
"inline__not-found_switch-text": 8,
"start__text": 10,
"sticker__button_add-set": 7,
"sticker__button_add-single": 5,
"sticker__button_remove-set": 3,
"sticker__button_remove-single": 1,
"sticker__text": 16,
"unknown-command__text": 15,
"sticker__text": 13,
"unknown-command__text": 12,
}
var enIndex = []uint32{ // 18 elements
var enIndex = []uint32{ // 17 elements
0x00000000, 0x0000002f, 0x00000043, 0x00000065,
0x00000075, 0x00000094, 0x000000a8, 0x000000c9,
0x000000d9, 0x00000100, 0x00000110, 0x00000120,
0x00000145, 0x0000016f, 0x00000186, 0x0000018b,
0x000001ad, 0x000001d0,
} // Size: 96 bytes
0x000000d9, 0x000000fe, 0x00000128, 0x0000013f,
0x00000144, 0x00000166, 0x00000189, 0x0000022f,
0x00000245,
} // Size: 92 bytes
const enData string = "" + // Size: 464 bytes
const enData string = "" + // Size: 581 bytes
"\x02📲 Sticker from %[1]v set has been imported!\x02🔥 Remove sticker\x02📲" +
" Set %[1]v has been imported!\x02🔥 Remove set\x02🔥 Sticker has been remo" +
"ved!\x02📙 Import sticker\x02🔥 Set %[1]v has been removed!\x02📚 Import se" +
"t\x02🐞 This language is already selected\x02⚙ Settings\x02👋🏻 Hello!\x02" +
"🤷🏻\u200d♂ Stickers not found\x02🕵🏻\u200d♂ Found %[1]v stickers\x02" +
"👋🏻 Hello, %[1]v!\x02Helo\x02🤷🏻\u200d♂ Unknown command\x02🤔 What to d" +
"o with this sticker?"
"t\x02🤷🏻\u200d♂ Stickers not found\x02🕵🏻\u200d♂ Found %[1]v stickers" +
"\x02👋🏻 Hello, %[1]v!\x02Helo\x02🤷🏻\u200d♂ Unknown command\x02🤔 What to " +
"do with this sticker?\x02🥳 4 November? It's a @toby3d birthday!\x0a\x0aI" +
"f you like this bot, then why not send him a congratulation along with a" +
" small gift? This will make him incredibly happy!\x02💸 Make a donation!"
var ruIndex = []uint32{ // 18 elements
var ruIndex = []uint32{ // 17 elements
0x00000000, 0x00000044, 0x00000063, 0x00000093,
0x000000b0, 0x000000cf, 0x000000fc, 0x0000011f,
0x0000014a, 0x00000175, 0x0000018f, 0x000001a6,
0x000001d9, 0x00000214, 0x00000232, 0x0000023f,
0x00000277, 0x000002ae,
} // Size: 96 bytes
0x0000014a, 0x0000017d, 0x000001b8, 0x000001d6,
0x000001e3, 0x0000021b, 0x00000252, 0x00000385,
0x000003b5,
} // Size: 92 bytes
const ruData string = "" + // Size: 686 bytes
const ruData string = "" + // Size: 949 bytes
"\x02📲 Стикер из набора %[1]v импортирован!\x02🔥 Убрать стикер\x02📲 Набор" +
" %[1]v импортирован!\x02🔥 Убрать набор\x02🔥 Стикер удалён\x02📙 Импортиро" +
"вать стикер\x02🔥 Набор %[1]v удалён\x02📚 Импортировать набор\x02🐞 Этот " +
"язык уже выбран\x02⚙ Настройки\x02👋🏻 Привет!\x02🤷🏻\u200d♂ Ничего не н" +
"айдено\x02🕵🏻\u200d♂ Найдено %[1]v стикеров\x02👋🏻 Привет, %[1]v!\x02По" +
"мощь\x02🤷🏻\u200d♂ Неизвестная команда\x02🤔 Что делать с этим стикером?"
"вать стикер\x02🔥 Набор %[1]v удалён\x02📚 Импортировать набор\x02🤷🏻" +
"\u200d♂ Ничего не найдено\x02🕵🏻\u200d♂ Найдено %[1]v стикеров\x02👋🏻 П" +
"ривет, %[1]v!\x02Помощь\x02🤷🏻\u200d♂ Неизвестная команда\x02🤔 Что дела" +
"ть с этим стикером?\x02🥳 4 Ноября? Это день рождения @toby3d!\x0a\x0aЕс" +
"ли тебе нравится этот бот, то почему бы не отправить ему поздравление в" +
"месте с небольшим подарком? Это несказанно осчастливит его!\x02💸 Сделат" +
"ь пожертвование!"
// Total table size 1342 bytes (1KiB); checksum: D59659D7
// Total table size 1714 bytes (1KiB); checksum: 845B0821

View File

@ -12,7 +12,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "call.Message.ReplyToMessage.Sticker.SetName"
}
]
},
@ -24,15 +24,15 @@
{
"id": "callback__text_add-set",
"message": "callback__text_add-set",
"translation": "📲 Set {SetName} has been imported!",
"translation": "📲 Set {Title} has been imported!",
"placeholders": [
{
"id": "SetName",
"id": "Title",
"string": "%[1]v",
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "set.Title"
}
]
},
@ -62,7 +62,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "s.SetName"
}
]
},
@ -71,21 +71,6 @@
"message": "sticker__button_add-set",
"translation": "📚 Import set"
},
{
"id": "callback__text_language-same",
"message": "callback__text_language-same",
"translation": "🐞 This language is already selected"
},
{
"id": "settings-command__text",
"message": "settings-command__text",
"translation": "⚙️ Settings"
},
{
"id": "callback__text_language",
"message": "callback__text_language",
"translation": "👋🏻 Hello!"
},
{
"id": "inline__not-found_switch-text",
"message": "inline__not-found_switch-text",
@ -117,7 +102,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "m.From.FullName()"
"expr": "msg.From.FullName()"
}
]
},
@ -135,6 +120,20 @@
"id": "sticker__text",
"message": "sticker__text",
"translation": "🤔 What to do with this sticker?"
},
{
"id": "birthday__message_text",
"message": "birthday__message_text",
"translation": "🥳 4 November? It's a @toby3d birthday!\n\nIf you like this bot, then why not send him a congratulation along with a small gift? This will make him incredibly happy!",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "birthday__button_text-donate",
"message": "birthday__button_text-donate",
"translation": "💸 Make a donation!",
"translatorComment": "Copied from source.",
"fuzzy": true
}
]
}

View File

@ -12,7 +12,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "call.Message.ReplyToMessage.Sticker.SetName"
}
]
},
@ -24,15 +24,15 @@
{
"id": "callback__text_add-set",
"message": "callback__text_add-set",
"translation": "📲 Set {SetName} has been imported!",
"translation": "📲 Set {Title} has been imported!",
"placeholders": [
{
"id": "SetName",
"id": "Title",
"string": "%[1]v",
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "set.Title"
}
]
},
@ -62,7 +62,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "s.SetName"
}
]
},
@ -71,21 +71,6 @@
"message": "sticker__button_add-set",
"translation": "📚 Import set"
},
{
"id": "callback__text_language-same",
"message": "callback__text_language-same",
"translation": "🐞 This language is already selected"
},
{
"id": "settings-command__text",
"message": "settings-command__text",
"translation": "⚙️ Settings"
},
{
"id": "callback__text_language",
"message": "callback__text_language",
"translation": "👋🏻 Hello!"
},
{
"id": "inline__not-found_switch-text",
"message": "inline__not-found_switch-text",
@ -117,7 +102,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "m.From.FullName()"
"expr": "msg.From.FullName()"
}
]
},
@ -135,6 +120,20 @@
"id": "sticker__text",
"message": "sticker__text",
"translation": "🤔 What to do with this sticker?"
},
{
"id": "birthday__message_text",
"message": "birthday__message_text",
"translation": "🥳 4 November? It's a @toby3d birthday!\n\nIf you like this bot, then why not send him a congratulation along with a small gift? This will make him incredibly happy!",
"translatorComment": "Copied from source.",
"fuzzy": true
},
{
"id": "birthday__button_text-donate",
"message": "birthday__button_text-donate",
"translation": "💸 Make a donation!",
"translatorComment": "Copied from source.",
"fuzzy": true
}
]
}

View File

@ -12,7 +12,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "call.Message.ReplyToMessage.Sticker.SetName"
}
]
},
@ -24,15 +24,15 @@
{
"id": "callback__text_add-set",
"message": "callback__text_add-set",
"translation": "📲 Набор {SetName} импортирован!",
"translation": "📲 Набор {Title} импортирован!",
"placeholders": [
{
"id": "SetName",
"id": "Title",
"string": "%[1]v",
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "set.Title"
}
]
},
@ -62,7 +62,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "s.SetName"
}
]
},
@ -71,21 +71,6 @@
"message": "sticker__button_add-set",
"translation": "📚 Импортировать набор"
},
{
"id": "callback__text_language-same",
"message": "callback__text_language-same",
"translation": "🐞 Этот язык уже выбран"
},
{
"id": "settings-command__text",
"message": "settings-command__text",
"translation": "⚙️ Настройки"
},
{
"id": "callback__text_language",
"message": "callback__text_language",
"translation": "👋🏻 Привет!"
},
{
"id": "inline__not-found_switch-text",
"message": "inline__not-found_switch-text",
@ -117,7 +102,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "m.From.FullName()"
"expr": "msg.From.FullName()"
}
]
},
@ -135,6 +120,16 @@
"id": "sticker__text",
"message": "sticker__text",
"translation": "🤔 Что делать с этим стикером?"
},
{
"id": "birthday__message_text",
"message": "birthday__message_text",
"translation": "🥳 4 Ноября? Это день рождения @toby3d!\n\nЕсли тебе нравится этот бот, то почему бы не отправить ему поздравление вместе с небольшим подарком? Это несказанно осчастливит его!"
},
{
"id": "birthday__button_text-donate",
"message": "birthday__button_text-donate",
"translation": "💸 Сделать пожертвование!"
}
]
}

View File

@ -12,7 +12,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "call.Message.ReplyToMessage.Sticker.SetName"
}
]
},
@ -24,15 +24,15 @@
{
"id": "callback__text_add-set",
"message": "callback__text_add-set",
"translation": "📲 Набор {SetName} импортирован!",
"translation": "📲 Набор {Title} импортирован!",
"placeholders": [
{
"id": "SetName",
"id": "Title",
"string": "%[1]v",
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "set.Title"
}
]
},
@ -62,7 +62,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "c.Message.ReplyToMessage.Sticker.SetName"
"expr": "s.SetName"
}
]
},
@ -71,21 +71,6 @@
"message": "sticker__button_add-set",
"translation": "📚 Импортировать набор"
},
{
"id": "callback__text_language-same",
"message": "callback__text_language-same",
"translation": "🐞 Этот язык уже выбран"
},
{
"id": "settings-command__text",
"message": "settings-command__text",
"translation": "⚙️ Настройки"
},
{
"id": "callback__text_language",
"message": "callback__text_language",
"translation": "👋🏻 Привет!"
},
{
"id": "inline__not-found_switch-text",
"message": "inline__not-found_switch-text",
@ -117,7 +102,7 @@
"type": "string",
"underlyingType": "string",
"argNum": 1,
"expr": "m.From.FullName()"
"expr": "msg.From.FullName()"
}
]
},
@ -135,6 +120,16 @@
"id": "sticker__text",
"message": "sticker__text",
"translation": "🤔 Что делать с этим стикером?"
},
{
"id": "birthday__message_text",
"message": "birthday__message_text",
"translation": "🥳 4 Ноября? Это день рождения @toby3d!\n\nЕсли тебе нравится этот бот, то почему бы не отправить ему поздравление вместе с небольшим подарком? Это несказанно осчастливит его!"
},
{
"id": "birthday__button_text-donate",
"message": "birthday__button_text-donate",
"translation": "💸 Сделать пожертвование!"
}
]
}

14
internal/common/common.go Normal file
View File

@ -0,0 +1,14 @@
package common
const (
DataAdd string = "add"
DataAddSet string = DataSet + DataSeparator + DataAdd
DataAddSticker string = DataSticker + DataSeparator + DataAdd
DataLanguage string = "language"
DataRemove string = "remove"
DataRemoveSet string = DataSet + DataSeparator + DataRemove
DataRemoveSticker string = DataSticker + DataSeparator + DataRemove
DataSeparator string = "@"
DataSet string = "set"
DataSticker string = "sticker"
)

View File

@ -1,249 +0,0 @@
package event
import (
"strings"
"time"
"gitlab.com/toby3d/mypackbot/internal/middleware"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/language"
"golang.org/x/text/language/display"
"golang.org/x/text/message"
)
func (event *Event) CallbackQuery(c *tg.CallbackQuery) error {
u, err := middleware.GetUser(event.store, c.From, time.Now().UTC().Unix())
if err != nil {
return err
}
parts := strings.Split(c.Data, ":")
switch parts[0] {
case "add":
switch parts[1] {
case "single":
return event.CallbackAddSingleSticker(u, c)
case "set":
return event.CallbackAddStickerSet(u, c)
}
case "remove":
switch parts[1] {
case "single":
return event.CallbackRemoveSingleSticker(u, c)
case "set":
return event.CallbackRemoveStickerSet(u, c)
}
case "language":
return event.CallbackSwitchLanguage(u, c, parts[1])
}
return nil
}
func (event *Event) CallbackAddSingleSticker(u *model.User, c *tg.CallbackQuery) (err error) {
answer := tg.NewAnswerCallbackQuery(c.ID)
p := middleware.GetPrinter(u.LanguageCode)
answer.Text = p.Sprintf("callback__text_add-single", c.Message.ReplyToMessage.Sticker.SetName)
if err = event.store.AddSticker(u, &model.Sticker{
CreatedAt: c.Message.ReplyToMessage.Date,
Emoji: c.Message.ReplyToMessage.Sticker.Emoji,
ID: c.Message.ReplyToMessage.Sticker.FileID,
IsAnimated: c.Message.ReplyToMessage.Sticker.IsAnimated,
SetName: c.Message.ReplyToMessage.Sticker.SetName,
}); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-single"), "remove:single"),
))
if len(c.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(markup.InlineKeyboard[0], c.Message.ReplyMarkup.InlineKeyboard[0][1])
}
if _, err = event.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: c.Message.Chat.ID,
InlineMessageID: c.InlineMessageID,
MessageID: c.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
func (event *Event) CallbackAddStickerSet(u *model.User, c *tg.CallbackQuery) (err error) {
answer := tg.NewAnswerCallbackQuery(c.ID)
set, err := event.bot.GetStickerSet(c.Message.ReplyToMessage.Sticker.SetName)
if err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
for i := range set.Stickers {
s, err := event.store.Stickers().GetOrCreate(&model.Sticker{
CreatedAt: time.Now().UTC().Unix(),
Emoji: set.Stickers[i].Emoji,
ID: set.Stickers[i].FileID,
IsAnimated: set.Stickers[i].IsAnimated,
SetName: set.Name,
})
if err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
if err = event.store.AddSticker(u, s); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
}
p := middleware.GetPrinter(u.LanguageCode)
answer.Text = p.Sprintf("callback__text_add-set", c.Message.ReplyToMessage.Sticker.SetName)
if err = event.store.AddStickersSet(u, c.Message.ReplyToMessage.Sticker.SetName); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-single"), "remove:single"),
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-set"), "remove:set"),
))
if _, err = event.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: c.Message.Chat.ID,
InlineMessageID: c.InlineMessageID,
MessageID: c.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
func (event *Event) CallbackRemoveSingleSticker(u *model.User, c *tg.CallbackQuery) (err error) {
answer := tg.NewAnswerCallbackQuery(c.ID)
p := middleware.GetPrinter(u.LanguageCode)
answer.Text = p.Sprintf("callback__text_remove-single")
if err = event.store.RemoveSticker(u, &model.Sticker{
CreatedAt: c.Message.ReplyToMessage.Date,
Emoji: c.Message.ReplyToMessage.Sticker.Emoji,
ID: c.Message.ReplyToMessage.Sticker.FileID,
IsAnimated: c.Message.ReplyToMessage.Sticker.IsAnimated,
SetName: c.Message.ReplyToMessage.Sticker.SetName,
}); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), "add:single"),
))
if len(c.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(markup.InlineKeyboard[0], c.Message.ReplyMarkup.InlineKeyboard[0][1])
}
if _, err = event.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: c.Message.Chat.ID,
InlineMessageID: c.InlineMessageID,
MessageID: c.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
func (event *Event) CallbackRemoveStickerSet(u *model.User, c *tg.CallbackQuery) (err error) {
answer := tg.NewAnswerCallbackQuery(c.ID)
p := middleware.GetPrinter(u.LanguageCode)
answer.Text = p.Sprintf("callback__text_remove-set", c.Message.ReplyToMessage.Sticker.SetName)
if err = event.store.RemoveStickersSet(u, c.Message.ReplyToMessage.Sticker.SetName); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), "add:single"),
))
if len(c.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0],
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-set"), "add:set"),
)
}
if _, err = event.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: c.Message.Chat.ID,
InlineMessageID: c.InlineMessageID,
MessageID: c.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
func (event *Event) CallbackSwitchLanguage(u *model.User, c *tg.CallbackQuery, lang string) (err error) {
answer := tg.NewAnswerCallbackQuery(c.ID)
p := message.NewPrinter(language.Make(u.LanguageCode))
if u.LanguageCode == lang {
answer.Text = p.Sprintf("callback__text_language-same")
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
timeStamp := time.Now().UTC().Unix()
if err = event.store.Users().Update(&model.User{
ID: u.ID,
LanguageCode: lang,
CreatedAt: u.CreatedAt,
LastSeen: timeStamp,
UpdatedAt: timeStamp,
}); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}
u = event.store.Users().Get(u.ID)
p = message.NewPrinter(language.Make(u.LanguageCode))
for i := range c.Message.ReplyMarkup.InlineKeyboard {
for j := range c.Message.ReplyMarkup.InlineKeyboard[i] {
parts := strings.Split(c.Message.ReplyMarkup.InlineKeyboard[i][j].CallbackData, ":")
languageName := display.Self.Name(language.Make(parts[1]))
text := "☑️" + languageName
if parts[1] == u.LanguageCode {
text = "✅" + languageName
}
c.Message.ReplyMarkup.InlineKeyboard[i][j].Text = text
}
}
if _, err = event.bot.EditMessageText(&tg.EditMessageTextParameters{
ChatID: c.Message.Chat.ID,
InlineMessageID: c.InlineMessageID,
MessageID: c.Message.ID,
ReplyMarkup: c.Message.ReplyMarkup,
Text: p.Sprintf("settings-command__text"),
}); err != nil {
return
}
answer.Text = p.Sprintf("callback__text_language")
_, err = event.bot.AnswerCallbackQuery(answer)
return err
}

View File

@ -1,18 +0,0 @@
package event
import (
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
type Event struct {
bot *tg.Bot
store store.Manager
}
func NewEvent(b *tg.Bot, s store.Manager) *Event {
return &Event{
bot: b,
store: s,
}
}

View File

@ -1,58 +0,0 @@
package event
import (
"strconv"
"strings"
"time"
"gitlab.com/toby3d/mypackbot/internal/middleware"
"gitlab.com/toby3d/mypackbot/internal/utils"
tg "gitlab.com/toby3d/telegram"
)
var replacer = strings.NewReplacer(
"personal:true", "",
"personal:false", "",
)
func (event *Event) InlineQuery(i *tg.InlineQuery) (err error) {
answer := tg.NewAnswerInlineQuery(i.ID)
answer.IsPersonal = !strings.Contains(i.Query, "personal:false")
answer.CacheTime = 1
if i.HasQuery() {
i.Query = replacer.Replace(i.Query)
i.Query, _ = utils.FixEmojiTone(i.Query)
i.Query = strings.TrimSpace(i.Query)
}
u, err := middleware.GetUser(event.store, i.From, time.Now().UTC().Unix())
if err != nil {
_, err = event.bot.AnswerInlineQuery(answer)
return err
}
p := middleware.GetPrinter(u.LanguageCode)
answer.SwitchPrivateMessageText = p.Sprintf("inline__not-found_switch-text")
answer.SwitchPrivateMessageParameter = "from_inline"
offset, _ := strconv.Atoi(i.Offset)
stickers, count := event.store.GetStickersList(u, offset, 50, i.Query)
if !answer.IsPersonal {
stickers, count = event.store.Stickers().GetList(offset, 50, i.Query)
}
if count != 0 && offset+50 < count {
answer.NextOffset = strconv.Itoa(offset + 50)
}
answer.SwitchPrivateMessageText = p.Sprintf("inline__found_switch-text", count)
answer.SwitchPrivateMessageParameter = "from_inline"
answer.Results = make([]interface{}, len(stickers), len(stickers))
for i := range stickers {
answer.Results[i] = tg.NewInlineQueryResultCachedSticker(stickers[i].ID, stickers[i].ID)
}
_, err = event.bot.AnswerInlineQuery(answer)
return err
}

View File

@ -1,132 +0,0 @@
package event
import (
"gitlab.com/toby3d/mypackbot/internal/middleware"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/language/display"
"golang.org/x/text/message"
)
func (event *Event) Message(m *tg.Message) error {
switch {
case m.IsCommand():
return event.Commands(m)
case m.IsSticker():
return event.Stickers(m)
}
return nil
}
func (event *Event) Commands(m *tg.Message) error {
u, err := middleware.GetUser(event.store, m.From, m.Date)
if err != nil {
return err
}
p := middleware.GetPrinter(u.LanguageCode)
switch {
case m.IsCommandEqual(tg.CommandStart):
return event.StartCommand(p, m)
case m.IsCommandEqual(tg.CommandHelp):
return event.HelpCommand(p, m)
case m.IsCommandEqual(tg.CommandSettings):
return event.SettingsCommand(u, p, m)
default:
return event.UnknownCommand(p, m)
}
}
func (event *Event) StartCommand(p *message.Printer, m *tg.Message) (err error) {
reply := tg.NewMessage(m.Chat.ID, p.Sprintf("start__text", m.From.FullName()))
reply.ReplyToMessageID = m.ID
_, err = event.bot.SendMessage(reply)
return err
}
func (event *Event) HelpCommand(p *message.Printer, m *tg.Message) (err error) {
reply := tg.NewMessage(m.Chat.ID, p.Sprintf("help__text"))
reply.ReplyToMessageID = m.ID
_, err = event.bot.SendMessage(reply)
return err
}
func (event *Event) UnknownCommand(p *message.Printer, m *tg.Message) (err error) {
reply := tg.NewMessage(m.Chat.ID, p.Sprintf("unknown-command__text"))
reply.ReplyToMessageID = m.ID
_, err = event.bot.SendMessage(reply)
return err
}
func (event *Event) SettingsCommand(u *model.User, p *message.Printer, m *tg.Message) (err error) {
reply := tg.NewMessage(m.Chat.ID, p.Sprintf("settings-command__text"))
reply.ReplyToMessageID = m.ID
markup := tg.NewInlineKeyboardMarkup()
// TODO(toby3d): Split on multiple columns
supportedLanguages := message.DefaultCatalog.Languages()
for _, supportedLanguage := range supportedLanguages {
base, _ := supportedLanguage.Base()
text := "☑️ "
if base.String() == u.LanguageCode {
text = "✅ "
}
text = text + display.Self.Name(supportedLanguage)
markup.InlineKeyboard = append(markup.InlineKeyboard, tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(text, "language:"+base.String()),
))
}
reply.ReplyMarkup = markup
_, err = event.bot.SendMessage(reply)
return err
}
func (event *Event) Stickers(m *tg.Message) error {
u, err := middleware.GetUser(event.store, m.From, m.Date)
if err != nil {
return err
}
s, err := event.store.Stickers().GetOrCreate(&model.Sticker{
ID: m.Sticker.FileID,
IsAnimated: m.Sticker.IsAnimated,
SetName: m.Sticker.SetName,
CreatedAt: m.Date,
})
if err != nil {
return err
}
us, err := event.store.GetSticker(u, s)
if err != nil {
return err
}
p := middleware.GetPrinter(u.LanguageCode)
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), "add:single"),
))
if s.SetName != "" {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0],
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-set"), "add:set"),
)
}
if us != nil {
markup = tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-single"), "remove:single"),
))
if s.SetName != "" {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0],
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-set"), "remove:set"),
)
}
}
reply := tg.NewMessage(m.Chat.ID, p.Sprintf("sticker__text"))
reply.ReplyToMessageID = m.ID
reply.ReplyMarkup = markup
_, err = event.bot.SendMessage(reply)
return err
}

View File

@ -0,0 +1,185 @@
package handler
import (
"context"
"gitlab.com/toby3d/mypackbot/internal/common"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/message"
)
func (h *Handler) isCallbackQuery(ctx context.Context, call *tg.CallbackQuery) (err error) {
switch call.Data {
case common.DataAddSticker:
err = h.callbackAddSticker(ctx, call)
case common.DataAddSet:
err = h.callbackAddSet(ctx, call)
case common.DataRemoveSticker:
err = h.callbackRemoveSticker(ctx, call)
case common.DataRemoveSet:
err = h.callbackRemoveSet(ctx, call)
}
return err
}
func (h *Handler) callbackAddSticker(ctx context.Context, call *tg.CallbackQuery) (err error) {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
s, _ := ctx.Value("sticker").(*model.Sticker)
answer := tg.NewAnswerCallbackQuery(call.ID)
answer.Text = p.Sprintf("callback__text_add-single", call.Message.ReplyToMessage.Sticker.SetName)
if err = h.store.AddSticker(u, s); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-single"), common.DataRemoveSticker),
))
if len(call.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0], call.Message.ReplyMarkup.InlineKeyboard[0][1],
)
}
if _, err = h.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: call.Message.Chat.ID,
InlineMessageID: call.InlineMessageID,
MessageID: call.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
func (h *Handler) callbackAddSet(ctx context.Context, call *tg.CallbackQuery) (err error) {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
s, _ := ctx.Value("sticker").(*model.Sticker)
answer := tg.NewAnswerCallbackQuery(call.ID)
set, err := h.bot.GetStickerSet(s.SetName)
if err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
for i := range set.Stickers {
if s, err = h.store.Stickers().GetOrCreate(&model.Sticker{
CreatedAt: call.Message.Date,
Emoji: set.Stickers[i].Emoji,
ID: set.Stickers[i].FileID,
IsAnimated: set.Stickers[i].IsAnimated,
SetName: set.Name,
}); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
if err = h.store.AddSticker(u, s); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
}
answer.Text = p.Sprintf("callback__text_add-set", set.Title)
if err = h.store.AddStickersSet(u, set.Name); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-single"), common.DataRemoveSticker),
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_remove-set"), common.DataRemoveSet),
))
if _, err = h.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: call.Message.Chat.ID,
InlineMessageID: call.InlineMessageID,
MessageID: call.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
func (h *Handler) callbackRemoveSticker(ctx context.Context, call *tg.CallbackQuery) (err error) {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
s, _ := ctx.Value("sticker").(*model.Sticker)
answer := tg.NewAnswerCallbackQuery(call.ID)
answer.Text = p.Sprintf("callback__text_remove-single")
if err = h.store.RemoveSticker(u, s); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), common.DataAddSticker),
))
if len(call.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0], call.Message.ReplyMarkup.InlineKeyboard[0][1],
)
}
if _, err = h.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: call.Message.Chat.ID,
InlineMessageID: call.InlineMessageID,
MessageID: call.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
func (h *Handler) callbackRemoveSet(ctx context.Context, call *tg.CallbackQuery) (err error) {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
s, _ := ctx.Value("sticker").(*model.Sticker)
answer := tg.NewAnswerCallbackQuery(call.ID)
answer.Text = p.Sprintf("callback__text_remove-set", s.SetName)
if err = h.store.RemoveStickersSet(u, s.SetName); err != nil {
answer.Text = "🐞 " + err.Error()
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), common.DataAddSticker),
))
if len(call.Message.ReplyMarkup.InlineKeyboard[0]) == 2 {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0],
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-set"), common.DataAddSet),
)
}
if _, err = h.bot.EditMessageReplyMarkup(&tg.EditMessageReplyMarkupParameters{
ChatID: call.Message.Chat.ID,
InlineMessageID: call.InlineMessageID,
MessageID: call.Message.ID,
ReplyMarkup: markup,
}); err != nil {
return
}
_, err = h.bot.AnswerCallbackQuery(answer)
return err
}

View File

@ -0,0 +1,35 @@
package handler
import (
"context"
"github.com/kirillDanshin/dlog"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
type Handler struct {
bot *tg.Bot
store store.Manager
}
func NewHandler(b *tg.Bot, s store.Manager) *Handler {
return &Handler{
bot: b,
store: s,
}
}
func (h *Handler) UpdateHandler(ctx context.Context, upd *tg.Update) (err error) {
switch {
case upd.IsMessage():
err = h.isMessage(ctx, upd.Message)
case upd.IsCallbackQuery():
err = h.isCallbackQuery(ctx, upd.CallbackQuery)
case upd.IsInlineQuery():
err = h.isInlineQuery(ctx, upd.InlineQuery)
default:
dlog.D(upd)
}
return err
}

View File

@ -0,0 +1,51 @@
package handler
import (
"context"
"strconv"
"strings"
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/utils"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/message"
)
func (h *Handler) isInlineQuery(ctx context.Context, inline *tg.InlineQuery) (err error) {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
answer := tg.NewAnswerInlineQuery(inline.ID)
answer.IsPersonal = !strings.Contains(inline.Query, "personal:false")
answer.CacheTime = 1
if inline.HasQuery() {
inline.Query = strings.Trim(inline.Query, "personal:true")
inline.Query = strings.Trim(inline.Query, "personal:false")
inline.Query = strings.TrimSpace(inline.Query)
inline.Query, _ = utils.FixEmojiTone(inline.Query)
}
answer.SwitchPrivateMessageText = p.Sprintf("inline__not-found_switch-text")
answer.SwitchPrivateMessageParameter = "from_inline"
offset, _ := strconv.Atoi(inline.Offset)
stickers, count := h.store.GetStickersList(u, offset, 50, inline.Query)
if !answer.IsPersonal {
stickers, count = h.store.Stickers().GetList(offset, 50, inline.Query)
}
if count > 0 && offset+50 < count {
answer.NextOffset = strconv.Itoa(offset + 50)
}
answer.SwitchPrivateMessageText = p.Sprintf("inline__found_switch-text", count)
answer.SwitchPrivateMessageParameter = "from_inline"
answer.Results = make([]interface{}, len(stickers), len(stickers))
for i := range stickers {
answer.Results[i] = tg.NewInlineQueryResultCachedSticker(stickers[i].ID, stickers[i].ID)
}
_, err = h.bot.AnswerInlineQuery(answer)
return err
}

View File

@ -0,0 +1,97 @@
package handler
import (
"context"
"gitlab.com/toby3d/mypackbot/internal/common"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/message"
)
func (h *Handler) isMessage(ctx context.Context, msg *tg.Message) (err error) {
switch {
case msg.IsCommand():
err = h.isCommand(ctx, msg)
case msg.IsSticker():
err = h.isSticker(ctx, msg)
}
return err
}
func (h *Handler) isCommand(ctx context.Context, msg *tg.Message) (err error) {
switch {
case msg.IsCommandEqual(tg.CommandStart):
err = h.commandStart(ctx, msg)
case msg.IsCommandEqual(tg.CommandHelp):
err = h.commandHelp(ctx, msg)
case msg.IsCommandEqual(tg.CommandSettings):
fallthrough
default:
err = h.commandUnknown(ctx, msg)
}
return err
}
func (h *Handler) commandStart(ctx context.Context, msg *tg.Message) (err error) {
p, _ := ctx.Value("printer").(*message.Printer)
reply := tg.NewMessage(msg.Chat.ID, p.Sprintf("start__text", msg.From.FullName()))
reply.ReplyToMessageID = msg.ID
_, err = h.bot.SendMessage(reply)
return err
}
func (h *Handler) commandHelp(ctx context.Context, msg *tg.Message) (err error) {
p, _ := ctx.Value("printer").(*message.Printer)
reply := tg.NewMessage(msg.Chat.ID, p.Sprintf("help__text"))
reply.ReplyToMessageID = msg.ID
_, err = h.bot.SendMessage(reply)
return err
}
func (h *Handler) commandUnknown(ctx context.Context, msg *tg.Message) (err error) {
p, _ := ctx.Value("printer").(*message.Printer)
reply := tg.NewMessage(msg.Chat.ID, p.Sprintf("unknown-command__text"))
reply.ReplyToMessageID = msg.ID
_, err = h.bot.SendMessage(reply)
return err
}
func (h *Handler) isSticker(ctx context.Context, msg *tg.Message) error {
u, _ := ctx.Value("user").(*model.User)
p, _ := ctx.Value("printer").(*message.Printer)
s, _ := ctx.Value("sticker").(*model.Sticker)
us, err := h.store.GetSticker(u, s)
if err != nil {
return err
}
markup := tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-single"), common.DataAddSticker),
))
if s.SetName != "" {
markup.InlineKeyboard[0] = append(
markup.InlineKeyboard[0],
tg.NewInlineKeyboardButton(p.Sprintf("sticker__button_add-set"), common.DataAddSet),
)
}
if us != nil {
markup = tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(tg.NewInlineKeyboardButton(
p.Sprintf("sticker__button_remove-single"),
common.DataRemoveSticker,
)))
if s.SetName != "" {
markup.InlineKeyboard[0] = append(markup.InlineKeyboard[0], tg.NewInlineKeyboardButton(
p.Sprintf("sticker__button_remove-set"),
common.DataRemoveSet,
))
}
}
reply := tg.NewMessage(msg.Chat.ID, p.Sprintf("sticker__text"))
reply.ReplyToMessageID = msg.ID
reply.ReplyMarkup = markup
_, err = h.bot.SendMessage(reply)
return err
}

View File

@ -0,0 +1,21 @@
package middleware
import (
"context"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func AcquirePrinter() Interceptor {
matcher := message.DefaultCatalog.Matcher()
return func(ctx context.Context, update *tg.Update, next model.UpdateFunc) error {
u, _ := ctx.Value("user").(*model.User)
tag, _, _ := matcher.Match(language.Make(u.LanguageCode))
printer := message.NewPrinter(tag)
ctx = context.WithValue(ctx, "printer", printer)
return next(ctx, update)
}
}

View File

@ -0,0 +1,70 @@
package middleware
import (
"context"
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
func AcquireSticker(bot *tg.Bot, store store.StickersManager) Interceptor {
return func(ctx context.Context, update *tg.Update, next model.UpdateFunc) (err error) {
var s *model.Sticker
switch {
case update.IsMessage():
if !update.Message.IsSticker() {
return next(ctx, update)
}
s = &model.Sticker{
ID: update.Message.Sticker.FileID,
IsAnimated: update.Message.Sticker.IsAnimated,
SetName: update.Message.Sticker.SetName,
Emoji: update.Message.Sticker.Emoji,
CreatedAt: update.Message.Date,
}
case update.IsCallbackQuery():
if !update.CallbackQuery.Message.IsReply() ||
!update.CallbackQuery.Message.ReplyToMessage.IsSticker() {
return next(ctx, update)
}
s = &model.Sticker{
ID: update.CallbackQuery.Message.ReplyToMessage.Sticker.FileID,
IsAnimated: update.CallbackQuery.Message.ReplyToMessage.Sticker.IsAnimated,
SetName: update.CallbackQuery.Message.ReplyToMessage.Sticker.SetName,
Emoji: update.CallbackQuery.Message.ReplyToMessage.Sticker.Emoji,
CreatedAt: update.CallbackQuery.Message.ReplyToMessage.Date,
}
default:
return next(ctx, update)
}
if s.SetName != "" {
go func() {
set, err := bot.GetStickerSet(s.SetName)
if err != nil {
return
}
for _, sticker := range set.Stickers {
store.GetOrCreate(&model.Sticker{
ID: sticker.FileID,
IsAnimated: sticker.IsAnimated,
SetName: set.Name,
Emoji: sticker.Emoji,
CreatedAt: s.CreatedAt,
})
}
}()
}
s, err = store.GetOrCreate(s)
if err != nil {
return err
}
return next(context.WithValue(ctx, "sticker", s), update)
}
}

View File

@ -0,0 +1,40 @@
package middleware
import (
"context"
"time"
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
func AcquireUser(us store.UsersManager) Interceptor {
return func(ctx context.Context, update *tg.Update, next model.UpdateFunc) error {
timeStamp := time.Now().UTC().Unix()
var from *tg.User
switch {
case update.IsMessage():
from = update.Message.From
timeStamp = update.Message.Date
case update.IsInlineQuery():
from = update.InlineQuery.From
case update.IsCallbackQuery():
from = update.CallbackQuery.From
}
u, err := us.GetOrCreate(&model.User{
ID: from.ID,
LanguageCode: from.LanguageCode,
CreatedAt: timeStamp,
UpdatedAt: timeStamp,
LastSeen: timeStamp,
})
if err != nil {
return err
}
return next(context.WithValue(ctx, "user", u), update)
}
}

View File

@ -0,0 +1,52 @@
package middleware
import (
"context"
"time"
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
"golang.org/x/text/message"
)
func Birthday(bot *tg.Bot, us store.UsersManager, bday time.Time) Interceptor {
return func(ctx context.Context, update *tg.Update, next model.UpdateFunc) (err error) {
if !update.IsMessage() {
return next(ctx, update)
}
u, _ := ctx.Value("user").(*model.User)
lastSeen := time.Unix(u.LastSeen, 0)
date := update.Message.Time()
before := time.Date(date.Year(), bday.Month(), bday.Day(), 0, 0, 0, 0, time.UTC)
after := before.AddDate(0, 0, 7)
if date.Before(before) || date.After(after) || lastSeen.After(before) {
return next(ctx, update)
}
// NOTE(toby3d): do this middleware only after sending all previous messages
if err = next(ctx, update); err != nil {
return err
}
p, _ := ctx.Value("printer").(*message.Printer)
reply := tg.NewMessage(update.Message.Chat.ID, p.Sprintf("birthday__message_text"))
reply.DisableNotification = false
reply.DisableWebPagePreview = false
reply.ParseMode = tg.StyleMarkdown
reply.ReplyMarkup = tg.NewInlineKeyboardMarkup(tg.NewInlineKeyboardRow(tg.NewInlineKeyboardButtonURL(
p.Sprintf("birthday__button_text-donate"), "https://toby3d.me/donate",
)))
if _, err = bot.SendMessage(reply); err != nil {
return err
}
u.LastSeen = date.Unix()
if err = us.Update(u); err != nil {
return err
}
return next(ctx, update)
}
}

View File

@ -1,10 +0,0 @@
package middleware
import (
"golang.org/x/text/language"
"golang.org/x/text/message"
)
func GetPrinter(code string) *message.Printer {
return message.NewPrinter(language.Make(code))
}

View File

@ -1,17 +0,0 @@
package middleware
import (
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
func GetUser(s store.Manager, u *tg.User, date int64) (*model.User, error) {
return s.Users().GetOrCreate(&model.User{
ID: u.ID,
LanguageCode: u.LanguageCode,
CreatedAt: date,
UpdatedAt: date,
LastSeen: date,
})
}

View File

@ -0,0 +1,29 @@
package middleware
import (
"context"
"gitlab.com/toby3d/mypackbot/internal/model"
tg "gitlab.com/toby3d/telegram"
)
type (
Interceptor func(context.Context, *tg.Update, model.UpdateFunc) error
UpdateHandler model.UpdateFunc
Chain []Interceptor
)
func (count UpdateHandler) Intercept(middleware Interceptor) UpdateHandler {
return func(ctx context.Context, upd *tg.Update) error {
return middleware(ctx, upd, model.UpdateFunc(count))
}
}
func (chain Chain) UpdateHandler(handler model.UpdateFunc) model.UpdateFunc {
current := UpdateHandler(handler)
for i := len(chain) - 1; i >= 0; i-- {
m := chain[i]
current = current.Intercept(m)
}
return model.UpdateFunc(current)
}

View File

@ -0,0 +1,30 @@
package middleware
import (
"context"
"time"
"gitlab.com/toby3d/mypackbot/internal/model"
"gitlab.com/toby3d/mypackbot/internal/model/store"
tg "gitlab.com/toby3d/telegram"
)
func UpdateLastSeen(us store.UsersManager) Interceptor {
return func(ctx context.Context, update *tg.Update, next model.UpdateFunc) error {
timeStamp := time.Now().UTC().Unix()
if update.IsMessage() {
timeStamp = update.Message.Date
}
u, _ := ctx.Value("user").(*model.User)
if time.Unix(u.LastSeen, 0).After(time.Unix(timeStamp, 0).Add(-1 * time.Hour)) {
return next(ctx, update)
}
u.LastSeen = timeStamp
if err := us.Update(u); err != nil {
return err
}
return next(context.WithValue(ctx, "user", u), update)
}
}

View File

@ -1,23 +1,28 @@
package model
import (
"context"
tg "gitlab.com/toby3d/telegram"
)
type (
// User represent a simple bot user
User struct {
CreatedAt int64 `json:"created_at"`
ID int `json:"id"`
LanguageCode string `json:"language_code"`
LastSeen int64 `json:"last_seen"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
LastSeen int64 `json:"last_seen"`
}
Users []*User
Sticker struct {
CreatedAt int64 `json:"created_at"`
Emoji string `json:"emoji"`
ID string `json:"id"`
IsAnimated bool `json:"is_animated"`
Emoji string `json:"emoji"`
SetName string `json:"set_name"`
IsAnimated bool `json:"is_animated"`
CreatedAt int64 `json:"created_at"`
}
Stickers []*Sticker
@ -31,6 +36,8 @@ type (
}
UserStickers []*UserSticker
UpdateFunc func(context.Context, *tg.Update) error
)
func (users Users) GetByID(id int) *User {

View File

@ -1,8 +1,12 @@
package internal
import (
"context"
"time"
"github.com/kirillDanshin/dlog"
"gitlab.com/toby3d/mypackbot/internal/event"
"gitlab.com/toby3d/mypackbot/internal/handler"
"gitlab.com/toby3d/mypackbot/internal/middleware"
tg "gitlab.com/toby3d/telegram"
)
@ -39,22 +43,17 @@ func (mpb *MyPackBot) Run() error {
})
}
e := event.NewEvent(mpb.bot, mpb.store)
h := handler.NewHandler(mpb.bot, mpb.store)
bDay := time.Date(0, time.November, 4, 0, 0, 0, 0, time.UTC)
chain := middleware.Chain{
middleware.AcquireUser(mpb.store.Users()),
middleware.AcquirePrinter(),
middleware.AcquireSticker(mpb.bot, mpb.store.Stickers()),
middleware.Birthday(mpb.bot, mpb.store.Users(), bDay),
middleware.UpdateLastSeen(mpb.store.Users()),
}
for update := range updates {
var err error
switch {
case update.IsMessage():
err = e.Message(update.Message)
case update.IsCallbackQuery():
err = e.CallbackQuery(update.CallbackQuery)
case update.IsInlineQuery():
err = e.InlineQuery(update.InlineQuery)
// case update.IsChosenInlineResult():
// err = e.ChosenInlineResult(update.ChosenInlineResult)
default:
dlog.D(update)
}
if err != nil {
if err := chain.UpdateHandler(h.UpdateHandler)(context.Background(), &update); err != nil {
dlog.Ln("ERROR:", err.Error())
}
}

View File

@ -50,6 +50,10 @@ func (store *InMemoryUsersStore) Update(u *model.User) error {
return store.Create(u)
}
if u.UpdatedAt <= 0 {
u.UpdatedAt = time.Now().UTC().Unix()
}
store.mutex.Lock()
for i := range store.users {
if store.users[i].ID != u.ID {