123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- package tg
- import (
- apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
- "fmt"
- "crypto/rand"
- "encoding/base64"
- )
- // The type wraps Telegram API's button to provide Action functionality.
- type Button struct {
- Text string
- Data string
- URL string
- SendLocation bool
- Action Action
- // Used to skip buttons in generating by functions.
- Valid bool
- }
- type ButtonMap map[string]Button
- // Returns the only location button in the map and if it is there at all.
- // The location map must be the ONLY one.
- func (btnMap ButtonMap) LocationButton() (Button, bool) {
- for _, btn := range btnMap {
- if btn.SendLocation {
- return btn, true
- }
- }
- return Button{}, false
- }
- // Represents the reply button row.
- type ButtonRow []Button
- // Returns new button with the specified text and no action.
- func Buttonf(format string, v ...any) Button {
- return Button{
- Text: fmt.Sprintf(format, v...),
- Valid: true,
- }
- }
- // Randomize buttons data to make the key unique.
- // No guaranties about collisions though.
- func (btn Button) Rand() Button {
- rData := make([]byte, 8)
- rand.Read(rData)
- data := make([]byte, base64.StdEncoding.EncodedLen(len(rData)))
- base64.StdEncoding.Encode(data, rData)
- btn.Data = string(data)
- return btn
- }
- // Set the URL for the button. Only for inline buttons.
- func (btn Button) WithURL(format string, v ...any) Button {
- btn.URL = fmt.Sprintf(format, v...)
- return btn
- }
- // Set the action when pressing the button.
- // By default is nil and does nothing.
- func (btn Button) WithAction(a Action) Button {
- btn.Action = a
- return btn
- }
- func (btn Button) WithData(dat string) Button {
- btn.Data = dat
- return btn
- }
- // Sets whether the button must send owner's location.
- func (btn Button) WithSendLocation(ok bool) Button {
- btn.SendLocation = ok
- return btn
- }
- func (btn Button) Go(pth Widget) Button {
- return btn.WithAction(WidgetGo{
- Path: pth,
- })
- }
- func (btn Button) GoWithArg(pth Widget, arg any) Button {
- return btn.WithAction(WidgetGo{
- Path: pth,
- Arg: arg,
- })
- }
- func (btn Button) ToTelegram() apix.KeyboardButton {
- ret := apix.NewKeyboardButton(btn.Text)
- if btn.SendLocation {
- ret.RequestLocation = true
- }
- return ret
- }
- func (btn Button) ToTelegramInline() apix.InlineKeyboardButton {
- if btn.Data != "" {
- return apix.NewInlineKeyboardButtonData(
- btn.Text,
- btn.Data,
- )
- }
- if btn.URL != "" {
- return apix.NewInlineKeyboardButtonURL(
- btn.Text,
- btn.URL,
- )
- }
- // If no match then return the data one with data the same as the text.
- return apix.NewInlineKeyboardButtonData(btn.Text, btn.Text)
- }
- // Return the key of the button to identify it by messages and callbacks.
- func (btn Button) Key() string {
- if btn.Data != "" {
- return btn.Data
- }
- // If no match then return the data one with data the same as the text.
- return btn.Text
- }
- func NewButtonRow(btns ...Button) ButtonRow {
- return btns
- }
|