lightningtipbot/internal/telegram/telegram.go
gohumble bf643f103d
🪄 update telebot v3 🤖 (#325)
* 🚧 minor changes to all handlers...

* 🚧 passing callback to tryEditStack

* 🚧 edit and delete callback messages

* 🚧 refactor again

* 🚧 uncomment this

* 🚧 using ctx.Message().Text

* 🚧 refactor

* 🚧 refactor

* 🚧 uncomment

* context not queruy

* 🚧 update forked lightningtipbot

* 🚧 reset ArticleResult

* fix inline receive

* readd shop

* remove chat from shopView

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
2022-03-27 22:19:38 +02:00

184 lines
4.9 KiB
Go

package telegram
import (
"fmt"
"strconv"
"time"
"github.com/LightningTipBot/LightningTipBot/internal/rate"
"github.com/eko/gocache/store"
log "github.com/sirupsen/logrus"
tb "gopkg.in/lightningtipbot/telebot.v3"
)
// getChatIdFromRecipient will parse the recipient to int64
func (bot *TipBot) getChatIdFromRecipient(to tb.Recipient) (int64, error) {
chatId, err := strconv.ParseInt(to.Recipient(), 10, 64)
if err != nil {
return 0, err
}
return chatId, nil
}
func (bot TipBot) tryForwardMessage(to tb.Recipient, what tb.Editable, options ...interface{}) (msg *tb.Message) {
rate.CheckLimit(to)
// ChatId is used for the keyboard
chatId, err := bot.getChatIdFromRecipient(to)
if err != nil {
log.Errorf("[tryForwardMessage] error converting message recipient to int64: %v", err)
return
}
msg, err = bot.Telegram.Forward(to, what, bot.appendMainMenu(chatId, to, options)...)
if err != nil {
log.Warnln(err.Error())
}
return
}
func (bot TipBot) trySendMessage(to tb.Recipient, what interface{}, options ...interface{}) (msg *tb.Message) {
rate.CheckLimit(to)
// ChatId is used for the keyboard
chatId, err := bot.getChatIdFromRecipient(to)
if err != nil {
log.Errorf("[trySendMessage] error converting message recipient to int64: %v", err)
return
}
log.Tracef("[trySendMessage] chatId: %d", chatId)
msg, err = bot.Telegram.Send(to, what, bot.appendMainMenu(chatId, to, options)...)
if err != nil {
log.Warnln(err.Error())
}
return
}
func (bot TipBot) trySendMessageEditable(to tb.Recipient, what interface{}, options ...interface{}) (msg *tb.Message) {
rate.CheckLimit(to)
msg, err := bot.Telegram.Send(to, what, options...)
if err != nil {
log.Warnln(err.Error())
}
return
}
func (bot TipBot) tryReplyMessage(to *tb.Message, what interface{}, options ...interface{}) (msg *tb.Message) {
rate.CheckLimit(to)
msg, err := bot.Telegram.Reply(to, what, bot.appendMainMenu(to.Chat.ID, to, options)...)
if err != nil {
log.Warnln(err.Error())
}
return
}
func (bot TipBot) tryEditMessage(to tb.Editable, what interface{}, options ...interface{}) (msg *tb.Message, err error) {
// get a sig for the rate limiter
sig, chat := to.MessageSig()
if chat != 0 {
sig = strconv.FormatInt(chat, 10)
}
rate.CheckLimit(sig)
_, chatId := to.MessageSig()
log.Tracef("[tryEditMessage] sig: %s, chatId: %d", sig, chatId)
msg, err = bot.Telegram.Edit(to, what, options...)
if err != nil {
log.Warnln(err.Error())
}
return
}
func (bot TipBot) tryDeleteMessage(msg tb.Editable) {
if !allowedToPerformAction(bot, msg, isAdminAndCanDelete) {
return
}
rate.CheckLimit(msg)
err := bot.Telegram.Delete(msg)
if err != nil {
log.Warnln(err.Error())
}
return
}
// allowedToPerformAction will check if bot is allowed to perform an action on the tb.Editable.
// this function will persist the admins list in cache for 5 minutes.
// if no admins list is found for this group, bot will always fetch a fresh list.
func allowedToPerformAction(bot TipBot, editable tb.Editable, action func(members []tb.ChatMember, me *tb.User) bool) bool {
switch editable.(type) {
case *tb.Message:
message := editable.(*tb.Message)
if message.Sender.ID == bot.Telegram.Me.ID {
break
}
chat := message.Chat
if chat.Type == tb.ChatSuperGroup || chat.Type == tb.ChatGroup {
admins, err := bot.Cache.Get(fmt.Sprintf("admins-%d", chat.ID))
if err != nil {
admins, err = bot.Telegram.AdminsOf(message.Chat)
if err != nil {
log.Warnln(err.Error())
return false
}
bot.Cache.Set(fmt.Sprintf("admins-%d", chat.ID), admins, &store.Options{Expiration: 5 * time.Minute})
}
if action(admins.([]tb.ChatMember), bot.Telegram.Me) {
return true
}
return false
}
}
return true
}
// isAdminAndCanDelete will check if me is in members list and allowed to delete messages
func isAdminAndCanDelete(members []tb.ChatMember, me *tb.User) bool {
for _, admin := range members {
if admin.User.ID == me.ID {
return admin.CanDeleteMessages
}
}
return false
}
// isOwner will check if user is owner of group
func (bot *TipBot) isOwner(chat *tb.Chat, me *tb.User) bool {
members, err := bot.Telegram.AdminsOf(chat)
if err != nil {
log.Warnln(err.Error())
return false
}
for _, admin := range members {
if admin.User.ID == me.ID && admin.Role == "creator" {
return true
}
}
return false
}
// isAdmin will check if user is admin in a group
func (bot *TipBot) isAdmin(chat *tb.Chat, me *tb.User) bool {
members, err := bot.Telegram.AdminsOf(chat)
if err != nil {
log.Warnln(err.Error())
return false
}
for _, admin := range members {
if admin.User.ID == me.ID {
return true
}
}
return false
}
// isAdmin will check if user is admin in a group
func (bot *TipBot) isAdminAndCanInviteUsers(chat *tb.Chat, me *tb.User) bool {
members, err := bot.Telegram.AdminsOf(chat)
if err != nil {
log.Warnln(err.Error())
return false
}
for _, admin := range members {
if admin.User.ID == me.ID {
return admin.CanInviteUsers
}
}
return false
}