Skip to content

Commit

Permalink
Merge pull request tucnak#509 from dzen-it/v3-webapp_support
Browse files Browse the repository at this point in the history
Web App support
  • Loading branch information
demget authored Oct 4, 2022
2 parents 2e4664a + 8342f1a commit 352b5c8
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 9 deletions.
27 changes: 27 additions & 0 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ func (b *Bot) ProcessUpdate(u Update) {
return
}

if m.WebAppData != nil {
b.handle(OnWebApp, c)
}

if m.ProximityAlert != nil {
b.handle(OnProximityAlert, c)
return
Expand Down Expand Up @@ -1103,6 +1107,29 @@ func (b *Bot) Respond(c *Callback, resp ...*CallbackResponse) error {
return err
}

// AnswerWebApp sends a response for a query from Web App and returns
// information about an inline message sent by a Web App on behalf of a user
func (b *Bot) AnswerWebApp(query *Query, resp *WebAppQueryResponse) (SentWebAppMessage, error) {
resp.WebAppQueryID = query.ID
resp.Result.Process(b)

data, err := b.Raw("answerWebAppQuery", resp)

if err != nil {
return SentWebAppMessage{}, err
}

var response struct {
Result SentWebAppMessage
}

if err := json.Unmarshal(data, &response); err != nil {
return SentWebAppMessage{}, wrapError(err)
}

return response.Result, err
}

// FileByID returns full file object including File.FilePath, allowing you to
// download the file from the server.
//
Expand Down
6 changes: 6 additions & 0 deletions bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@ func TestBotProcessUpdate(t *testing.T) {
return nil
})

b.Handle(OnWebApp, func(c Context) error {
assert.Equal(t, "webapp", c.Message().WebAppData.Data)
return nil
})

b.ProcessUpdate(Update{Message: &Message{Text: "/start"}})
b.ProcessUpdate(Update{Message: &Message{Text: "/start@other_bot"}})
b.ProcessUpdate(Update{Message: &Message{Text: "hello"}})
Expand Down Expand Up @@ -345,6 +350,7 @@ func TestBotProcessUpdate(t *testing.T) {
b.ProcessUpdate(Update{PreCheckoutQuery: &PreCheckoutQuery{ID: "checkout"}})
b.ProcessUpdate(Update{Poll: &Poll{ID: "poll"}})
b.ProcessUpdate(Update{PollAnswer: &PollAnswer{PollID: "poll"}})
b.ProcessUpdate(Update{Message: &Message{WebAppData: &WebAppData{Data: "webapp"}}})
}

func TestBotOnError(t *testing.T) {
Expand Down
19 changes: 13 additions & 6 deletions callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,13 @@ type InlineButton struct {
// It will be used as a callback endpoint.
Unique string `json:"unique,omitempty"`

Text string `json:"text"`
URL string `json:"url,omitempty"`
Data string `json:"callback_data,omitempty"`
InlineQuery string `json:"switch_inline_query,omitempty"`
InlineQueryChat string `json:"switch_inline_query_current_chat"`
Login *Login `json:"login_url,omitempty"`
Text string `json:"text"`
URL string `json:"url,omitempty"`
Data string `json:"callback_data,omitempty"`
InlineQuery string `json:"switch_inline_query,omitempty"`
InlineQueryChat string `json:"switch_inline_query_current_chat"`
WebApp *WebAppInfo `json:"web_app,omitempty"`
Login *Login `json:"login_url,omitempty"`
}

// With returns a copy of the button with data.
Expand Down Expand Up @@ -129,6 +130,12 @@ type Login struct {
WriteAccess bool `json:"request_write_access,omitempty"`
}

// WebAppInfo represents a parameter of the inline keyboard button
// or the keyboard button used to launch Web App.
type WebAppInfo struct {
URL string `json:"url"`
}

// MarshalJSON implements json.Marshaler interface.
// It needed to avoid InlineQueryChat and Login fields conflict.
// If you have Login field in your button, InlineQueryChat must be skipped.
Expand Down
12 changes: 12 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ type Context interface {
// See Respond from bot.go.
Respond(resp ...*CallbackResponse) error

// AnswerWebApp sends a response to the Web App query.
// See AnswerWebApp from bot.go.
AnswerWebApp(resp *WebAppQueryResponse) error

// Get retrieves data from the context.
Get(key string) interface{}

Expand Down Expand Up @@ -454,6 +458,14 @@ func (c *nativeContext) Respond(resp ...*CallbackResponse) error {
return c.b.Respond(c.u.Callback, resp...)
}

func (c *nativeContext) AnswerWebApp(resp *WebAppQueryResponse) error {
if c.u.Query == nil {
return errors.New("telebot: context inline query is nil")
}
_, err := c.b.AnswerWebApp(c.u.Query, resp)
return err
}

func (c *nativeContext) Set(key string, value interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
Expand Down
12 changes: 12 additions & 0 deletions inline.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,15 @@ func inferIQR(result Result) error {

return nil
}

// WebAppQueryResponse builds a response to an web app query.
type WebAppQueryResponse struct {
// (Required) Unique identifier for the query to be answered
WebAppQueryID string `json:"web_app_query_id"`
// (Required) A object describing the message to be sent
Result Result `json:"result"`
}

type SentWebAppMessage struct {
InlineMessageID string `json:"inline_message_id"`
}
6 changes: 6 additions & 0 deletions media.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ type Venue struct {
GooglePlaceType string `json:"google_place_type,omitempty"`
}

// WebAppData object represents a data sent from a Web App to the bot
type WebAppData struct {
Data string `json:"data"`
ButtonText string `json:"button_text"`
}

// Dice object represents a dice with a random value
// from 1 to 6 for currently supported base emoji.
type Dice struct {
Expand Down
3 changes: 3 additions & 0 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ type Message struct {
// For a service message, a voice chat schedule in the chat.
VoiceChatScheduled *VoiceChatScheduled `json:"voice_chat_scheduled,omitempty"`

// For a data sent by a Web App
WebAppData *WebAppData `json:"web_app_data,omitempty"`

// For a service message, represents the content of a service message,
// sent whenever a user in the chat triggers a proximity alert set by another user.
ProximityAlert *ProximityAlert `json:"proximity_alert_triggered,omitempty"`
Expand Down
7 changes: 4 additions & 3 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,10 @@ func (r *ReplyMarkup) copy() *ReplyMarkup {
type ReplyButton struct {
Text string `json:"text"`

Contact bool `json:"request_contact,omitempty"`
Location bool `json:"request_location,omitempty"`
Poll PollType `json:"request_poll,omitempty"`
Contact bool `json:"request_contact,omitempty"`
Location bool `json:"request_location,omitempty"`
Poll PollType `json:"request_poll,omitempty"`
WebApp WebAppInfo `json:"request_web_app,omitempty"`
}

// MarshalJSON implements json.Marshaler. It allows to pass
Expand Down
3 changes: 3 additions & 0 deletions telebot.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ const (

// Will fire on auto delete timer set.
OnAutoDeleteTimer = "\amessage_auto_delete_timer_changed"

// Will fire on the web app data.
OnWebApp = "\aweb_app"
)

// ChatAction is a client-side status indicating bot activity.
Expand Down

0 comments on commit 352b5c8

Please sign in to comment.