Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions markup.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,31 @@ type WebAppInfo struct {
URL string `json:"url"`
}

// KeyboardButtonStyle defines the visual style of an inline keyboard button.
type KeyboardButtonStyle struct {
BgPrimary bool `json:"bg_primary,omitempty"`
BgDanger bool `json:"bg_danger,omitempty"`
BgSuccess bool `json:"bg_success,omitempty"`
Icon *int64 `json:"icon,omitempty"`
}

// InlineKeyboardButton is one button of an inline keyboard. Exactly one of the
// optional action fields should be set.
type InlineKeyboardButton struct {
Text string `json:"text"`
URL string `json:"url,omitempty"`
CallbackData string `json:"callback_data,omitempty"`
WebApp *WebAppInfo `json:"web_app,omitempty"`
SwitchInlineQuery *string `json:"switch_inline_query,omitempty"`
SwitchInlineQueryCurrentChat *string `json:"switch_inline_query_current_chat,omitempty"`
Pay bool `json:"pay,omitempty"`
Text string `json:"text"`
URL string `json:"url,omitempty"`
CallbackData string `json:"callback_data,omitempty"`
WebApp *WebAppInfo `json:"web_app,omitempty"`
Style *KeyboardButtonStyle `json:"style,omitempty"`
SwitchInlineQuery *string `json:"switch_inline_query,omitempty"`
SwitchInlineQueryCurrentChat *string `json:"switch_inline_query_current_chat,omitempty"`
Pay bool `json:"pay,omitempty"`
}

func (s *InlineKeyboardButton) Styled(style *KeyboardButtonStyle) InlineKeyboardButton {
s.Style = style

return *s
}

// InlineKeyboardMarkup is an inline keyboard that appears beneath a message.
Expand Down
33 changes: 27 additions & 6 deletions markup_to_tg.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,40 @@ func replyMarkupToTg(m ReplyMarkup) (tg.ReplyMarkupClass, error) {
}

func inlineButtonToTg(btn InlineKeyboardButton) (tg.KeyboardButtonClass, error) {
var opts []markup.StyleOption

if btn.Style != nil {
s := btn.Style
if s.Icon != nil {
opts = append(opts, markup.StyleIcon(*s.Icon))
}

if s.BgDanger {
opts = append(opts, markup.StyleBgDanger())
}

if s.BgPrimary {
opts = append(opts, markup.StyleBgPrimary())
}

if s.BgSuccess {
opts = append(opts, markup.StyleBgSuccess())
}
}

switch {
case btn.URL != "":
return markup.URL(btn.Text, btn.URL), nil
return markup.URL(btn.Text, btn.URL, opts...), nil
case btn.CallbackData != "":
return markup.Callback(btn.Text, []byte(btn.CallbackData)), nil
return markup.Callback(btn.Text, []byte(btn.CallbackData), opts...), nil
case btn.WebApp != nil:
return markup.WebView(btn.Text, btn.WebApp.URL), nil
return markup.WebView(btn.Text, btn.WebApp.URL, opts...), nil
case btn.SwitchInlineQuery != nil:
return markup.SwitchInline(btn.Text, *btn.SwitchInlineQuery, false), nil
return markup.SwitchInline(btn.Text, *btn.SwitchInlineQuery, false, opts...), nil
case btn.SwitchInlineQueryCurrentChat != nil:
return markup.SwitchInline(btn.Text, *btn.SwitchInlineQueryCurrentChat, true), nil
return markup.SwitchInline(btn.Text, *btn.SwitchInlineQueryCurrentChat, true, opts...), nil
case btn.Pay:
return markup.Buy(btn.Text), nil
return markup.Buy(btn.Text, opts...), nil
default:
return nil, &Error{Code: 400, Description: "Bad Request: text buttons are unallowed in the inline keyboard"}
}
Expand Down
41 changes: 38 additions & 3 deletions pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ type Options struct {
// IdleTimeout shuts down a bot that has not been borrowed for this long.
// Zero disables idle collection (RunGC then does nothing).
IdleTimeout time.Duration

// BotOptions configures each bot individually.
BotOptions func(token string) botapi.Options

// Configure registers handlers before Bot.Run.
Configure func(token string, bot *botapi.Bot) error
}

// Pool is a concurrency-safe set of bots keyed by token.
Expand Down Expand Up @@ -138,13 +144,32 @@ func (p *Pool) start(tok Token) (*managed, error) {

m := &managed{ready: make(chan struct{}), db: db}

bot, err := botapi.New(tok.String(), botapi.Options{
botOptions := botapi.Options{
AppID: p.opt.AppID,
AppHash: p.opt.AppHash,
Logger: botLog,
Storage: store,
OnStart: func(context.Context) { m.markReady(nil) },
})
}

if p.opt.BotOptions != nil {
botOptions = p.opt.BotOptions(tok.String())
botOptions.AppID = p.opt.AppID
botOptions.AppHash = p.opt.AppHash
botOptions.Logger = botLog
botOptions.Storage = store
}

onStart := botOptions.OnStart

botOptions.OnStart = func(ctx context.Context) {
if onStart != nil {
onStart(ctx)
}

m.markReady(nil)
}

bot, err := botapi.New(tok.String(), botOptions)
if err != nil {
if db != nil {
_ = db.Close()
Expand All @@ -153,6 +178,16 @@ func (p *Pool) start(tok Token) (*managed, error) {
return nil, err
}

if p.opt.Configure != nil {
if err := p.opt.Configure(tok.String(), bot); err != nil {
if db != nil {
_ = db.Close()
}

return nil, errors.Wrap(err, "configure bot")
}
}

m.bot = bot

ctx, cancel := context.WithCancel(context.Background())
Expand Down
Loading