v0.5.0 #8
31
api.go
31
api.go
@@ -7,8 +7,27 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.nix13.pw/scuroneko/slog"
|
||||
)
|
||||
|
||||
type Api struct {
|
||||
token string
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewAPI(token string) *Api {
|
||||
l := slog.CreateLogger().Level(GetLoggerLevel()).Prefix("API")
|
||||
l.AddWriter(l.CreateJsonStdoutWriter())
|
||||
return &Api{
|
||||
token: token,
|
||||
logger: l,
|
||||
}
|
||||
}
|
||||
func (api *Api) CloseApi() {
|
||||
api.logger.Close()
|
||||
}
|
||||
|
||||
type ApiResponse[R any] struct {
|
||||
Ok bool `json:"ok"`
|
||||
Description string `json:"description,omitempty"`
|
||||
@@ -24,21 +43,21 @@ type TelegramRequest[R, P any] struct {
|
||||
func NewRequest[R, P any](method string, params P) TelegramRequest[R, P] {
|
||||
return TelegramRequest[R, P]{method: method, params: params}
|
||||
}
|
||||
func (r TelegramRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
func (r TelegramRequest[R, P]) Do(api *Api) (*R, error) {
|
||||
var buf bytes.Buffer
|
||||
err := json.NewEncoder(&buf).Encode(r.params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bot.requestLogger != nil {
|
||||
bot.requestLogger.Debugln(strings.ReplaceAll(fmt.Sprintf(
|
||||
if api.logger != nil {
|
||||
api.logger.Debugln(strings.ReplaceAll(fmt.Sprintf(
|
||||
"POST https://api.telegram.org/bot%s/%s %s",
|
||||
"<TOKEN>", r.method, buf.String(),
|
||||
), "\n", ""))
|
||||
}
|
||||
|
||||
req, err := http.Post(fmt.Sprintf("https://api.telegram.org/bot%s/%s", bot.token, r.method), "application/json", &buf)
|
||||
req, err := http.Post(fmt.Sprintf("https://api.telegram.org/bot%s/%s", api.token, r.method), "application/json", &buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -48,8 +67,8 @@ func (r TelegramRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bot.requestLogger != nil {
|
||||
bot.requestLogger.Debugln(fmt.Sprintf("RES %s %s", r.method, string(data)))
|
||||
if api.logger != nil {
|
||||
api.logger.Debugln(fmt.Sprintf("RES %s %s", r.method, string(data)))
|
||||
}
|
||||
|
||||
response := new(ApiResponse[R])
|
||||
|
||||
14
bot.go
14
bot.go
@@ -37,6 +37,9 @@ type Bot struct {
|
||||
runners []Runner
|
||||
|
||||
dbContext *DatabaseContext
|
||||
api *Api
|
||||
|
||||
dbWriterRequested extypes.Slice[*slog.Logger]
|
||||
|
||||
updateOffset int
|
||||
updateTypes []string
|
||||
@@ -75,12 +78,14 @@ func LoadPrefixesFromEnv() []string {
|
||||
}
|
||||
func NewBot(settings *BotSettings) *Bot {
|
||||
updateQueue := extypes.CreateQueue[*Update](256)
|
||||
api := NewAPI(settings.Token)
|
||||
bot := &Bot{
|
||||
updateOffset: 0, plugins: make([]Plugin, 0), debug: settings.Debug, errorTemplate: "%s",
|
||||
prefixes: settings.Prefixes, updateTypes: make([]string, 0), runners: make([]Runner, 0),
|
||||
updateQueue: updateQueue,
|
||||
updateQueue: updateQueue, api: api, dbWriterRequested: make([]*slog.Logger, 0),
|
||||
token: settings.Token,
|
||||
}
|
||||
bot.dbWriterRequested = bot.dbWriterRequested.Push(api.logger)
|
||||
|
||||
if len(settings.ErrorTemplate) > 0 {
|
||||
bot.errorTemplate = settings.ErrorTemplate
|
||||
@@ -118,7 +123,7 @@ func NewBot(settings *BotSettings) *Bot {
|
||||
}
|
||||
}
|
||||
|
||||
u, err := bot.GetMe()
|
||||
u, err := api.GetMe()
|
||||
if err != nil {
|
||||
bot.logger.Fatal(err)
|
||||
}
|
||||
@@ -150,6 +155,9 @@ func (b *Bot) AddDatabaseLogger(writer func(db *DatabaseContext) slog.LoggerWrit
|
||||
if b.requestLogger != nil {
|
||||
b.requestLogger.AddWriter(w)
|
||||
}
|
||||
for _, l := range b.dbWriterRequested {
|
||||
l.AddWriter(w)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -251,7 +259,7 @@ func (b *Bot) Run() {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx := &MsgContext{Bot: b, Update: u}
|
||||
ctx := &MsgContext{Bot: b, Update: u, Api: b.api}
|
||||
for _, middleware := range b.middlewares {
|
||||
middleware.Execute(ctx, b.dbContext)
|
||||
}
|
||||
|
||||
12
handler.go
12
handler.go
@@ -35,6 +35,18 @@ func (b *Bot) handleMessage(update *Update, ctx *MsgContext) {
|
||||
if !strings.HasPrefix(text, cmd) {
|
||||
continue
|
||||
}
|
||||
requestParts := strings.Split(text, " ")
|
||||
cmdParts := strings.Split(cmd, " ")
|
||||
isValid := true
|
||||
for i, part := range cmdParts {
|
||||
if part != requestParts[i] {
|
||||
isValid = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx.Text = strings.TrimSpace(text[len(cmd):])
|
||||
ctx.Args = strings.Split(ctx.Text, " ")
|
||||
|
||||
@@ -41,11 +41,11 @@ func (in *InlineKeyboard) AddLine() *InlineKeyboard {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
183
methods.go
183
methods.go
@@ -23,7 +23,7 @@ func (b *Bot) Updates() ([]*Update, error) {
|
||||
}
|
||||
|
||||
req := NewRequest[[]*Update]("getUpdates", params)
|
||||
res, err := req.Do(b)
|
||||
res, err := req.Do(b.api)
|
||||
if err != nil {
|
||||
return []*Update{}, err
|
||||
}
|
||||
@@ -47,30 +47,143 @@ func (b *Bot) Updates() ([]*Update, error) {
|
||||
return updates, err
|
||||
}
|
||||
|
||||
func (b *Bot) GetMe() (*User, error) {
|
||||
func (api *Api) GetMe() (*User, error) {
|
||||
req := NewRequest[User, EmptyParams]("getMe", NoParams)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
func (api *Api) LogOut() (bool, error) {
|
||||
req := NewRequest[bool, EmptyParams]("logOut", NoParams)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return *res, nil
|
||||
}
|
||||
func (api *Api) Close() (bool, error) {
|
||||
req := NewRequest[bool, EmptyParams]("close", NoParams)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return *res, nil
|
||||
}
|
||||
|
||||
type SendMessageP struct {
|
||||
BusinessConnectionID string `json:"business_connection_id,omitempty"`
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
DirectMessageTopicID int `json:"direct_message_topic_id,omitempty"`
|
||||
|
||||
Text string `json:"text"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
Entities []*MessageEntity `json:"entities,omitempty"`
|
||||
LinkPreviewOptions *LinkPreviewOptions `json:"link_preview_options,omitempty"`
|
||||
DisableNotifications bool `json:"disable_notifications,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
AllowPaidBroadcast bool `json:"allow_paid_broadcast,omitempty"`
|
||||
MessageEffectID string `json:"message_effect_id,omitempty"`
|
||||
|
||||
SuggestedPostParameters *SuggestedPostParameters `json:"suggested_post_parameters,omitempty"`
|
||||
ReplyParameters *ReplyParameters `json:"reply_parameters,omitempty"`
|
||||
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) SendMessage(params *SendMessageP) (*Message, error) {
|
||||
func (api *Api) SendMessage(params *SendMessageP) (*Message, error) {
|
||||
req := NewRequest[Message, SendMessageP]("sendMessage", *params)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type ForwardMessageP struct {
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
DirectMessageTopicID int `json:"direct_message_topic_id,omitempty"`
|
||||
|
||||
MessageID int `json:"message_id,omitempty"`
|
||||
FromChatID int `json:"from_chat_id,omitempty"`
|
||||
VideoStartTimestamp int `json:"video_start_timestamp,omitempty"`
|
||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
|
||||
MessageEffectID string `json:"message_effect_id,omitempty"`
|
||||
SuggestedPostParameters *SuggestedPostParameters `json:"suggested_post_parameters,omitempty"`
|
||||
}
|
||||
|
||||
func (api *Api) ForwardMessage(params ForwardMessageP) (*Message, error) {
|
||||
req := NewRequest[Message]("forwardMessage", params)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type ForwardMessagesP struct {
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
DirectMessageTopicID int `json:"direct_message_topic_id,omitempty"`
|
||||
|
||||
FromChatID int `json:"from_chat_id,omitempty"`
|
||||
MessageIDs []int `json:"message_ids,omitempty"`
|
||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
}
|
||||
|
||||
func (api *Api) ForwardMessages(params ForwardMessagesP) ([]int, error) {
|
||||
req := NewRequest[[]int]("forwardMessages", params)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return []int{}, err
|
||||
}
|
||||
return *res, nil
|
||||
}
|
||||
|
||||
type CopyMessageP struct {
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
DirectMessageTopicID int `json:"direct_message_topic_id,omitempty"`
|
||||
|
||||
FromChatID int `json:"from_chat_id"`
|
||||
MessageID int `json:"message_id"`
|
||||
VideoStartTimestamp int `json:"video_start_timestamp,omitempty"`
|
||||
Caption string `json:"caption,omitempty"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
|
||||
CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"`
|
||||
ShowCaptionAboveMedia bool `json:"show_caption_above_media,omitempty"`
|
||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
AllowPaidBroadcast bool `json:"allow_paid_broadcast,omitempty"`
|
||||
MessageEffectID string `json:"message_effect_id,omitempty"`
|
||||
|
||||
SuggestedPostParameters *SuggestedPostParameters `json:"suggested_post_parameters,omitempty"`
|
||||
ReplyParameters *ReplyParameters `json:"reply_parameters,omitempty"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (api *Api) CopyMessage(params CopyMessageP) (int, error) {
|
||||
req := NewRequest[int]("copyMessage", params)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return *res, nil
|
||||
}
|
||||
|
||||
type CopyMessagesP struct {
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
DirectMessageTopicID int `json:"direct_message_topic_id,omitempty"`
|
||||
|
||||
FromChatID int `json:"from_chat_id,omitempty"`
|
||||
MessageIDs []int `json:"message_ids,omitempty"`
|
||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
RemoveCaption bool `json:"remove_caption,omitempty"`
|
||||
}
|
||||
|
||||
func (api *Api) CopyMessages(params CopyMessagesP) ([]int, error) {
|
||||
req := NewRequest[[]int]("copyMessages", params)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return []int{}, err
|
||||
}
|
||||
return *res, nil
|
||||
}
|
||||
|
||||
type SendPhotoBaseP struct {
|
||||
@@ -92,22 +205,28 @@ type SendPhotoP struct {
|
||||
BusinessConnectionID string `json:"business_connection_id,omitempty"`
|
||||
ChatID int `json:"chat_id"`
|
||||
MessageThreadID int `json:"message_thread_id,omitempty"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
DirectMessagesTopicID int `json:"direct_messages_topic_id,omitempty"`
|
||||
|
||||
Photo string `json:"photo"`
|
||||
Caption string `json:"caption,omitempty"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"`
|
||||
|
||||
ShowCaptionAboveMedia bool `json:"show_caption_above_media,omitempty"`
|
||||
HasSpoiler bool `json:"has_spoiler,omitempty"`
|
||||
DisableNotifications bool `json:"disable_notifications,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
AllowPaidBroadcast bool `json:"allow_paid_broadcast,omitempty"`
|
||||
MessageEffectID string `json:"message_effect_id,omitempty"`
|
||||
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
Photo string `json:"photo"`
|
||||
|
||||
SuggestedPostParameters *SuggestedPostParameters `json:"suggested_post_parameters,omitempty"`
|
||||
ReplyParameters *ReplyParameters `json:"reply_parameters,omitempty"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) SendPhoto(params *SendPhotoP) (*Message, error) {
|
||||
func (api *Api) SendPhoto(params *SendPhotoP) (*Message, error) {
|
||||
req := NewRequest[Message]("sendPhoto", params)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type EditMessageTextP struct {
|
||||
@@ -117,12 +236,12 @@ 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"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) EditMessageText(params *EditMessageTextP) (*Message, error) {
|
||||
func (api *Api) EditMessageText(params *EditMessageTextP) (*Message, error) {
|
||||
req := NewRequest[Message]("editMessageText", params)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type EditMessageCaptionP struct {
|
||||
@@ -132,12 +251,12 @@ type EditMessageCaptionP struct {
|
||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
||||
Caption string `json:"caption"`
|
||||
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
||||
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) EditMessageCaption(params *EditMessageCaptionP) (*Message, error) {
|
||||
func (api *Api) EditMessageCaption(params *EditMessageCaptionP) (*Message, error) {
|
||||
req := NewRequest[Message]("editMessageCaption", params)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type DeleteMessageP struct {
|
||||
@@ -145,9 +264,9 @@ type DeleteMessageP struct {
|
||||
MessageID int `json:"message_id"`
|
||||
}
|
||||
|
||||
func (b *Bot) DeleteMessage(params *DeleteMessageP) (bool, error) {
|
||||
func (api *Api) DeleteMessage(params *DeleteMessageP) (bool, error) {
|
||||
req := NewRequest[bool]("deleteMessage", params)
|
||||
ok, err := req.Do(b)
|
||||
ok, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -162,9 +281,9 @@ type AnswerCallbackQueryP struct {
|
||||
CacheTime int `json:"cache_time,omitempty"`
|
||||
}
|
||||
|
||||
func (b *Bot) AnswerCallbackQuery(params *AnswerCallbackQueryP) (bool, error) {
|
||||
func (api *Api) AnswerCallbackQuery(params *AnswerCallbackQueryP) (bool, error) {
|
||||
req := NewRequest[bool]("answerCallbackQuery", params)
|
||||
ok, err := req.Do(b)
|
||||
ok, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -175,9 +294,9 @@ type GetFileP struct {
|
||||
FileId string `json:"file_id"`
|
||||
}
|
||||
|
||||
func (b *Bot) GetFile(params *GetFileP) (*File, error) {
|
||||
func (api *Api) GetFile(params *GetFileP) (*File, error) {
|
||||
req := NewRequest[File]("getFile", params)
|
||||
return req.Do(b)
|
||||
return req.Do(api)
|
||||
}
|
||||
|
||||
type SendChatActionP struct {
|
||||
@@ -187,9 +306,9 @@ type SendChatActionP struct {
|
||||
Action ChatActions `json:"action"`
|
||||
}
|
||||
|
||||
func (b *Bot) SendChatAction(params SendChatActionP) (bool, error) {
|
||||
func (api *Api) SendChatAction(params SendChatActionP) (bool, error) {
|
||||
req := NewRequest[bool]("sendChatAction", params)
|
||||
res, err := req.Do(b)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -206,9 +325,9 @@ type SetMessageReactionEmojiP struct {
|
||||
Reaction []ReactionTypeEmoji `json:"reaction"`
|
||||
}
|
||||
|
||||
func (b *Bot) SetMessageReactionEmoji(params SetMessageReactionEmojiP) (bool, error) {
|
||||
func (api *Api) SetMessageReactionEmoji(params SetMessageReactionEmojiP) (bool, error) {
|
||||
req := NewRequest[bool]("setMessageReaction", params)
|
||||
res, err := req.Do(b)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -220,9 +339,9 @@ type SetMessageReactionCustomEmojiP struct {
|
||||
Reaction []ReactionTypeCustomEmoji `json:"reaction"`
|
||||
}
|
||||
|
||||
func (b *Bot) SetMessageReactionCustom(params SetMessageReactionCustomEmojiP) (bool, error) {
|
||||
func (api *Api) SetMessageReactionCustom(params SetMessageReactionCustomEmojiP) (bool, error) {
|
||||
req := NewRequest[bool]("setMessageReaction", params)
|
||||
res, err := req.Do(b)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -233,9 +352,9 @@ type SetMessageReactionPaidP struct {
|
||||
SetMessageReactionP
|
||||
}
|
||||
|
||||
func (b *Bot) SetMessageReactionPaid(params SetMessageReactionPaidP) (bool, error) {
|
||||
func (api *Api) SetMessageReactionPaid(params SetMessageReactionPaidP) (bool, error) {
|
||||
req := NewRequest[bool]("setMessageReaction", params)
|
||||
res, err := req.Do(b)
|
||||
res, err := req.Do(api)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import "fmt"
|
||||
|
||||
type MsgContext struct {
|
||||
Bot *Bot
|
||||
Api *Api
|
||||
|
||||
Msg *Message
|
||||
Update *Update
|
||||
From *User
|
||||
@@ -33,9 +35,9 @@ func (ctx *MsgContext) edit(messageId int, text string, keyboard *InlineKeyboard
|
||||
if keyboard != nil {
|
||||
params.ReplyMarkup = keyboard.Get()
|
||||
}
|
||||
msg, err := ctx.Bot.EditMessageText(params)
|
||||
msg, err := ctx.Api.EditMessageText(params)
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
return nil
|
||||
}
|
||||
return &AnswerMessage{
|
||||
@@ -47,7 +49,7 @@ func (m *AnswerMessage) Edit(text string) *AnswerMessage {
|
||||
}
|
||||
func (ctx *MsgContext) EditCallback(text string, keyboard *InlineKeyboard) *AnswerMessage {
|
||||
if ctx.CallbackMsgId == 0 {
|
||||
ctx.Bot.logger.Errorln("Can't edit non-callback update message")
|
||||
ctx.Api.logger.Errorln("Can't edit non-callback update message")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,9 +69,9 @@ func (ctx *MsgContext) editPhotoText(messageId int, text string, kb *InlineKeybo
|
||||
if kb != nil {
|
||||
params.ReplyMarkup = kb.Get()
|
||||
}
|
||||
msg, err := ctx.Bot.EditMessageCaption(params)
|
||||
msg, err := ctx.Api.EditMessageCaption(params)
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
}
|
||||
return &AnswerMessage{
|
||||
MessageID: msg.MessageID, ctx: ctx, Text: text, IsMedia: true,
|
||||
@@ -77,7 +79,7 @@ func (ctx *MsgContext) editPhotoText(messageId int, text string, kb *InlineKeybo
|
||||
}
|
||||
func (m *AnswerMessage) EditCaption(text string) *AnswerMessage {
|
||||
if m.MessageID == 0 {
|
||||
m.ctx.Bot.logger.Errorln("Can't edit caption message, message id is zero")
|
||||
m.ctx.Api.logger.Errorln("Can't edit caption message, message id is zero")
|
||||
return m
|
||||
}
|
||||
return m.ctx.editPhotoText(m.MessageID, text, nil)
|
||||
@@ -96,9 +98,9 @@ func (ctx *MsgContext) answer(text string, keyboard *InlineKeyboard) *AnswerMess
|
||||
params.ReplyMarkup = keyboard.Get()
|
||||
}
|
||||
|
||||
msg, err := ctx.Bot.SendMessage(params)
|
||||
msg, err := ctx.Api.SendMessage(params)
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
return nil
|
||||
}
|
||||
return &AnswerMessage{
|
||||
@@ -125,9 +127,9 @@ func (ctx *MsgContext) answerPhoto(photoId, text string, kb *InlineKeyboard) *An
|
||||
if kb != nil {
|
||||
params.ReplyMarkup = kb.Get()
|
||||
}
|
||||
msg, err := ctx.Bot.SendPhoto(params)
|
||||
msg, err := ctx.Api.SendPhoto(params)
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
return &AnswerMessage{
|
||||
ctx: ctx, Text: text, IsMedia: true,
|
||||
}
|
||||
@@ -144,12 +146,12 @@ func (ctx *MsgContext) AnswerPhotoKeyboard(photoId, text string, kb *InlineKeybo
|
||||
}
|
||||
|
||||
func (ctx *MsgContext) delete(messageId int) {
|
||||
_, err := ctx.Bot.DeleteMessage(&DeleteMessageP{
|
||||
_, err := ctx.Api.DeleteMessage(&DeleteMessageP{
|
||||
ChatID: ctx.Msg.Chat.ID,
|
||||
MessageID: messageId,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
}
|
||||
}
|
||||
func (m *AnswerMessage) Delete() {
|
||||
@@ -163,12 +165,12 @@ func (ctx *MsgContext) answerCallbackQuery(url, text string, showAlert bool) {
|
||||
if len(ctx.CallbackQueryId) == 0 {
|
||||
return
|
||||
}
|
||||
_, err := ctx.Bot.AnswerCallbackQuery(&AnswerCallbackQueryP{
|
||||
_, err := ctx.Api.AnswerCallbackQuery(&AnswerCallbackQueryP{
|
||||
CallbackQueryID: ctx.CallbackQueryId,
|
||||
Text: text, ShowAlert: showAlert, URL: url,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
}
|
||||
}
|
||||
func (ctx *MsgContext) AnswerCbQuery() {
|
||||
@@ -185,11 +187,11 @@ func (ctx *MsgContext) AnswerCbQueryUrl(u string) {
|
||||
}
|
||||
|
||||
func (ctx *MsgContext) SendAction(action ChatActions) {
|
||||
_, err := ctx.Bot.SendChatAction(SendChatActionP{
|
||||
_, err := ctx.Api.SendChatAction(SendChatActionP{
|
||||
ChatID: ctx.Msg.Chat.ID, Action: action,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Bot.logger.Errorln(err)
|
||||
ctx.Api.logger.Errorln(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ func (p *PluginBuilder) Middleware(middleware *PluginMiddleware) *PluginBuilder
|
||||
|
||||
func (p *PluginBuilder) Build() Plugin {
|
||||
if len(p.commands) == 0 && len(p.payloads) == 0 {
|
||||
log.Println("no command or payloads")
|
||||
log.Printf("no command or payloads for %s", p.name)
|
||||
}
|
||||
return Plugin{
|
||||
Name: p.name,
|
||||
|
||||
32
types.go
32
types.go
@@ -85,11 +85,13 @@ type MessageEntity struct {
|
||||
type ReplyParameters struct {
|
||||
MessageID int `json:"message_id"`
|
||||
ChatID int `json:"chat_id,omitempty"`
|
||||
|
||||
AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"`
|
||||
Quote string `json:"quote,omitempty"`
|
||||
QuoteParsingMode string `json:"quote_parsing_mode,omitempty"`
|
||||
QuoteEntities []*MessageEntity `json:"quote_entities,omitempty"`
|
||||
QuotePosition int `json:"quote_postigin,omitempty"`
|
||||
QuotePosition int `json:"quote_position,omitempty"`
|
||||
ChecklistTaskID int `json:"checklist_task_id,omitempty"`
|
||||
}
|
||||
|
||||
type PhotoSize struct {
|
||||
@@ -108,6 +110,20 @@ type LinkPreviewOptions struct {
|
||||
ShowAboveText bool `json:"show_above_text,omitempty"`
|
||||
}
|
||||
|
||||
type ReplyMarkup struct {
|
||||
InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard,omitempty"`
|
||||
|
||||
Keyboard [][]int `json:"keyboard,omitempty"`
|
||||
IsPersistent bool `json:"is_persistent,omitempty"`
|
||||
ResizeKeyboard bool `json:"resize_keyboard,omitempty"`
|
||||
OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`
|
||||
InputFieldPlaceholder string `json:"input_field_placeholder,omitempty"`
|
||||
Selective bool `json:"selective,omitempty"`
|
||||
|
||||
RemoveKeyboard bool `json:"remove_keyboard,omitempty"`
|
||||
|
||||
ForceReply bool `json:"force_reply,omitempty"`
|
||||
}
|
||||
type InlineKeyboardMarkup struct {
|
||||
InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard,omitempty"`
|
||||
}
|
||||
@@ -194,3 +210,17 @@ const (
|
||||
ChatActionFindLocation ChatActions = "find_location"
|
||||
ChatActionUploadVideoNone ChatActions = "upload_video_none"
|
||||
)
|
||||
|
||||
type SuggestedPostPrice struct {
|
||||
Currency string `json:"currency"`
|
||||
Amount int `json:"amount"`
|
||||
}
|
||||
type SuggestedPostInfo struct {
|
||||
State string `json:"state"` //State of the suggested post. Currently, it can be one of “pending”, “approved”, “declined”.
|
||||
Price SuggestedPostPrice `json:"price"`
|
||||
SendDate int `json:"send_date"`
|
||||
}
|
||||
type SuggestedPostParameters struct {
|
||||
Price SuggestedPostPrice `json:"price"`
|
||||
SendDate int `json:"send_date"`
|
||||
}
|
||||
|
||||
24
uploader.go
24
uploader.go
@@ -8,14 +8,22 @@ import (
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"git.nix13.pw/scuroneko/slog"
|
||||
)
|
||||
|
||||
type Uploader struct {
|
||||
bot *Bot
|
||||
api *Api
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewUploader(bot *Bot) *Uploader {
|
||||
return &Uploader{bot: bot}
|
||||
func NewUploader(api *Api) *Uploader {
|
||||
logger := slog.CreateLogger().Level(GetLoggerLevel()).Prefix("UPLOADER")
|
||||
logger.AddWriter(logger.CreateJsonStdoutWriter())
|
||||
return &Uploader{api, logger}
|
||||
}
|
||||
func (u *Uploader) Close() {
|
||||
u.logger.Close()
|
||||
}
|
||||
|
||||
type UploaderFileType string
|
||||
@@ -56,8 +64,8 @@ func NewUploaderRequest[R, P any](method string, file UploaderFile, params P) Up
|
||||
return UploaderRequest[R, P]{method, file, params}
|
||||
}
|
||||
|
||||
func (u UploaderRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", bot.token, u.method)
|
||||
func (u UploaderRequest[R, P]) Do(up *Uploader) (*R, error) {
|
||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", up.api.token, u.method)
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
w := multipart.NewWriter(buf)
|
||||
@@ -87,7 +95,7 @@ func (u UploaderRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
bot.logger.Debugln("UPLOADER REQ", u.method)
|
||||
up.logger.Debugln("UPLOADER REQ", u.method)
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -98,7 +106,7 @@ func (u UploaderRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bot.logger.Debugln("UPLOADER RES", u.method, string(body))
|
||||
up.logger.Debugln("UPLOADER RES", u.method, string(body))
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("[%d] %s", res.StatusCode, string(body))
|
||||
}
|
||||
@@ -116,7 +124,7 @@ func (u UploaderRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
|
||||
func (u *Uploader) UploadPhoto(file UploaderFile, params SendPhotoBaseP) (*Message, error) {
|
||||
req := NewUploaderRequest[Message]("sendPhoto", file, params)
|
||||
return req.Do(u.bot)
|
||||
return req.Do(u)
|
||||
}
|
||||
|
||||
func uploaderTypeByExt(filename string) UploaderFileType {
|
||||
|
||||
11
utils.go
11
utils.go
@@ -3,9 +3,20 @@ package laniakea
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"git.nix13.pw/scuroneko/slog"
|
||||
)
|
||||
|
||||
func GetLoggerLevel() slog.LogLevel {
|
||||
level := slog.FATAL
|
||||
if os.Getenv("DEBUG") == "true" {
|
||||
level = slog.DEBUG
|
||||
}
|
||||
return level
|
||||
}
|
||||
|
||||
// MapToStruct unsafe function
|
||||
func MapToStruct(m map[string]any, s any) error {
|
||||
data, err := json.Marshal(m)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package laniakea
|
||||
|
||||
const (
|
||||
VersionString = "0.3.9"
|
||||
VersionString = "0.4.0"
|
||||
VersionMajor = 0
|
||||
VersionMinor = 3
|
||||
VersionPatch = 9
|
||||
VersionMinor = 4
|
||||
VersionPatch = 0
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user