inline keyboard
This commit is contained in:
77
bot.go
77
bot.go
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/vinovest/sqlx"
|
||||
@@ -69,6 +70,8 @@ type MsgContext struct {
|
||||
Bot *Bot
|
||||
Msg *Message
|
||||
Update *Update
|
||||
From *User
|
||||
CallbackMsgId int
|
||||
FromID int
|
||||
Prefix string
|
||||
Text string
|
||||
@@ -221,6 +224,7 @@ func (b *Bot) Run() {
|
||||
for {
|
||||
queue := b.updateQueue
|
||||
if queue.IsEmpty() {
|
||||
time.Sleep(time.Millisecond * 25)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -265,6 +269,7 @@ func (b *Bot) handleMessage(update *Update, ctx *MsgContext) {
|
||||
}
|
||||
|
||||
ctx.FromID = update.Message.From.ID
|
||||
ctx.From = update.Message.From
|
||||
ctx.Msg = update.Message
|
||||
text = strings.TrimSpace(text)
|
||||
prefix, hasPrefix := b.checkPrefixes(text)
|
||||
@@ -298,6 +303,12 @@ func (b *Bot) handleCallback(update *Update, ctx *MsgContext) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.FromID = update.CallbackQuery.From.ID
|
||||
ctx.From = update.CallbackQuery.From
|
||||
ctx.Msg = update.CallbackQuery.Message
|
||||
ctx.CallbackMsgId = update.CallbackQuery.Message.MessageID
|
||||
ctx.Args = data.Args
|
||||
|
||||
for _, plugin := range b.plugins {
|
||||
_, ok := plugin.Payloads[data.Command]
|
||||
if !ok {
|
||||
@@ -325,6 +336,40 @@ type AnswerMessage struct {
|
||||
ctx *MsgContext
|
||||
}
|
||||
|
||||
func (ctx *MsgContext) edit(messageId int, text string, keyboard *InlineKeyboard) *AnswerMessage {
|
||||
params := &EditMessageTextP{
|
||||
MessageID: messageId,
|
||||
ChatID: ctx.Msg.Chat.ID,
|
||||
Text: text,
|
||||
ParseMode: ParseMD,
|
||||
}
|
||||
if keyboard != nil {
|
||||
params.ReplyMarkup = keyboard.Get()
|
||||
}
|
||||
msg, err := ctx.Bot.EditMessageText(params)
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Error(err)
|
||||
return nil
|
||||
}
|
||||
return &AnswerMessage{
|
||||
MessageID: msg.MessageID, ctx: ctx, Text: text, IsMedia: false,
|
||||
}
|
||||
}
|
||||
func (m *AnswerMessage) Edit(text string) *AnswerMessage {
|
||||
return m.ctx.edit(m.MessageID, text, nil)
|
||||
}
|
||||
func (ctx *MsgContext) EditCallback(text string, keyboard *InlineKeyboard) *AnswerMessage {
|
||||
if ctx.CallbackMsgId == 0 {
|
||||
ctx.Bot.logger.Error("Can't edit non-callback update message")
|
||||
return nil
|
||||
}
|
||||
|
||||
return ctx.edit(ctx.CallbackMsgId, text, keyboard)
|
||||
}
|
||||
func (ctx *MsgContext) EditCallbackf(format string, keyboard *InlineKeyboard, args ...any) *AnswerMessage {
|
||||
return ctx.EditCallback(fmt.Sprintf(format, args...), keyboard)
|
||||
}
|
||||
|
||||
func (ctx *MsgContext) answer(text string, keyboard *InlineKeyboard) *AnswerMessage {
|
||||
params := &SendMessageP{
|
||||
ChatID: ctx.Msg.Chat.ID,
|
||||
@@ -369,31 +414,6 @@ func (ctx *MsgContext) AnswerPhoto(photoId string, text string) *AnswerMessage {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AnswerMessage) Edit(text string) *AnswerMessage {
|
||||
var msg *Message
|
||||
var err error
|
||||
if m.IsMedia {
|
||||
msg, err = m.ctx.Bot.EditMessageCaption(&EditMessageCaptionP{
|
||||
MessageID: m.MessageID,
|
||||
ChatID: m.ctx.Msg.Chat.ID,
|
||||
Caption: text,
|
||||
ParseMode: ParseMD,
|
||||
})
|
||||
} else {
|
||||
msg, err = m.ctx.Bot.EditMessageText(&EditMessageTextP{
|
||||
MessageID: m.MessageID,
|
||||
ChatID: m.ctx.Msg.Chat.ID,
|
||||
Text: text,
|
||||
ParseMode: ParseMD,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
m.ctx.Bot.logger.Error(err)
|
||||
}
|
||||
m.MessageID = msg.MessageID
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *AnswerMessage) Delete() {
|
||||
_, err := m.ctx.Bot.DeleteMessage(&DeleteMessageP{
|
||||
MessageID: m.MessageID, ChatID: m.ctx.Msg.Chat.ID,
|
||||
@@ -421,14 +441,14 @@ func (b *Bot) Logger() *Logger {
|
||||
|
||||
type ApiResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Result map[string]interface{} `json:"result,omitempty"`
|
||||
Result map[string]any `json:"result,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
ErrorCode int `json:"error_code,omitempty"`
|
||||
}
|
||||
|
||||
type ApiResponseA struct {
|
||||
Ok bool `json:"ok"`
|
||||
Result []interface{} `json:"result,omitempty"`
|
||||
Result []any `json:"result,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
ErrorCode int `json:"error_code,omitempty"`
|
||||
}
|
||||
@@ -458,9 +478,10 @@ func (b *Bot) request(methodName string, params any) (map[string]interface{}, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.requestLogger.Debug(fmt.Sprintf("RES %s %s", methodName, string(data)))
|
||||
response := new(ApiResponse)
|
||||
|
||||
var result map[string]interface{}
|
||||
var result map[string]any
|
||||
|
||||
err = json.Unmarshal(data, &response)
|
||||
if err != nil {
|
||||
|
||||
35
keyboard.go
35
keyboard.go
@@ -1,49 +1,70 @@
|
||||
package laniakea
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type InlineKeyboard struct {
|
||||
CurrentLine []InlineKeyboardButton
|
||||
Lines [][]InlineKeyboardButton
|
||||
maxRow int
|
||||
}
|
||||
|
||||
func NewInlineKeyboard() *InlineKeyboard {
|
||||
func NewInlineKeyboard(maxRow int) *InlineKeyboard {
|
||||
return &InlineKeyboard{
|
||||
CurrentLine: make([]InlineKeyboardButton, 0),
|
||||
Lines: make([][]InlineKeyboardButton, 0),
|
||||
maxRow: maxRow,
|
||||
}
|
||||
}
|
||||
|
||||
func (in *InlineKeyboard) append(button InlineKeyboardButton) *InlineKeyboard {
|
||||
if len(in.CurrentLine) == in.maxRow {
|
||||
in.AddLine()
|
||||
}
|
||||
in.CurrentLine = append(in.CurrentLine, button)
|
||||
return in
|
||||
}
|
||||
func (in *InlineKeyboard) AddUrlButton(text, url string) *InlineKeyboard {
|
||||
return in.append(InlineKeyboardButton{Text: text, URL: url})
|
||||
}
|
||||
func (in *InlineKeyboard) AddCallbackButton(text string, data CallbackData) *InlineKeyboard {
|
||||
return in.append(InlineKeyboardButton{Text: text, CallbackData: data.ToJson()})
|
||||
func (in *InlineKeyboard) AddCallbackButton(text string, cmd string, args ...any) *InlineKeyboard {
|
||||
return in.append(InlineKeyboardButton{Text: text, CallbackData: NewCallbackData(cmd, args...).ToJson()})
|
||||
}
|
||||
|
||||
func (in *InlineKeyboard) AddLine() *InlineKeyboard {
|
||||
if len(in.CurrentLine) == 0 {
|
||||
return in
|
||||
}
|
||||
in.Lines = append(in.Lines, in.CurrentLine)
|
||||
in.CurrentLine = make([]InlineKeyboardButton, 0)
|
||||
return in
|
||||
}
|
||||
func (in *InlineKeyboard) Get() *InlineKeyboardMarkup {
|
||||
func (in *InlineKeyboard) Get() InlineKeyboardMarkup {
|
||||
if len(in.CurrentLine) > 0 {
|
||||
in.Lines = append(in.Lines, in.CurrentLine)
|
||||
}
|
||||
return &InlineKeyboardMarkup{
|
||||
return InlineKeyboardMarkup{
|
||||
InlineKeyboard: in.Lines,
|
||||
}
|
||||
}
|
||||
|
||||
type CallbackData struct {
|
||||
Command string `json:"cmd"`
|
||||
Args []any `json:"args"`
|
||||
Args []string `json:"args"`
|
||||
}
|
||||
|
||||
func NewCallbackData(command string, args ...any) *CallbackData {
|
||||
stringArgs := make([]string, len(args))
|
||||
for i, arg := range args {
|
||||
stringArgs[i] = fmt.Sprint(arg)
|
||||
}
|
||||
return &CallbackData{
|
||||
Command: command,
|
||||
Args: stringArgs,
|
||||
}
|
||||
}
|
||||
func (d *CallbackData) ToJson() string {
|
||||
data, err := json.Marshal(d)
|
||||
if err != nil {
|
||||
|
||||
25
methods.go
25
methods.go
@@ -1,11 +1,14 @@
|
||||
package laniakea
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var NoParams = make(map[string]interface{})
|
||||
var NoParams = make(map[string]any)
|
||||
|
||||
func (b *Bot) Updates() ([]*Update, error) {
|
||||
params := make(map[string]interface{})
|
||||
params := make(map[string]any)
|
||||
params["offset"] = b.updateOffset
|
||||
params["timeout"] = 30
|
||||
params["allowed_updates"] = b.updateTypes
|
||||
@@ -15,12 +18,20 @@ func (b *Bot) Updates() ([]*Update, error) {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*Update, 0)
|
||||
for _, u := range data["data"].([]interface{}) {
|
||||
for _, u := range data["data"].([]any) {
|
||||
updateObj := new(Update)
|
||||
err = MapToStruct(u.(map[string]interface{}), updateObj)
|
||||
data, err := json.Marshal(u)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
err = json.Unmarshal(data, updateObj)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
//err = MapToStruct(u.(map[string]any), updateObj)
|
||||
//if err != nil {
|
||||
// return res, err
|
||||
//}
|
||||
b.updateOffset = updateObj.UpdateID + 1
|
||||
err = b.updateQueue.Enqueue(updateObj)
|
||||
if err != nil {
|
||||
@@ -62,8 +73,7 @@ type SendMessageP struct {
|
||||
AllowPaidBroadcast bool `json:"allow_paid_broadcast,omitempty"`
|
||||
MessageEffectID string `json:"message_effect_id,omitempty"`
|
||||
ReplyParameters *ReplyParameters `json:"reply_parameters,omitempty"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
// ReplyKeyboardMarkup *ReplyKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) SendMessage(params *SendMessageP) (*Message, error) {
|
||||
@@ -109,6 +119,7 @@ type EditMessageTextP struct {
|
||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
||||
Text string `json:"text"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) EditMessageText(params *EditMessageTextP) (*Message, error) {
|
||||
|
||||
12
types.go
12
types.go
@@ -12,9 +12,9 @@ type Update struct {
|
||||
DeletedBusinessMessage *Message `json:"deleted_business_messages,omitempty"`
|
||||
MessageReaction *MessageReactionUpdated `json:"message_reaction,omitempty"`
|
||||
MessageReactionCount *MessageReactionCountUpdated `json:"message_reaction_count,omitempty"`
|
||||
CallbackQuery *CallbackQuery `json:"callback_query,omitempty"`
|
||||
InlineQuery int
|
||||
ChosenInlineResult int
|
||||
CallbackQuery *CallbackQuery `json:"callback_query,omitempty"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
@@ -44,7 +44,7 @@ type Chat struct {
|
||||
}
|
||||
|
||||
type MessageReplyMarkup struct {
|
||||
InlineKeyboard *InlineKeyboardMarkup `json:"inline_keyboard"`
|
||||
InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
@@ -68,8 +68,6 @@ type InaccessableMessage struct {
|
||||
}
|
||||
|
||||
type MaybeInaccessibleMessage struct {
|
||||
Message
|
||||
InaccessableMessage
|
||||
}
|
||||
|
||||
type MessageEntity struct {
|
||||
@@ -109,7 +107,7 @@ type LinkPreviewOptions struct {
|
||||
}
|
||||
|
||||
type InlineKeyboardMarkup struct {
|
||||
InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
|
||||
InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard,omitempty"`
|
||||
}
|
||||
|
||||
type InlineKeyboardButton struct {
|
||||
@@ -124,8 +122,8 @@ type ReplyKeyboardMarkup struct {
|
||||
|
||||
type CallbackQuery struct {
|
||||
ID string `json:"id"`
|
||||
From *User `json:"user"`
|
||||
Message *MaybeInaccessibleMessage `json:"message"`
|
||||
From *User `json:"from"`
|
||||
Message *Message `json:"message"`
|
||||
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user