Improved inline API. TODO proper result types.

pull/108/head
Ian Byrd 7 years ago
parent 51ce032c7d
commit 612ab345bd

@ -350,7 +350,7 @@ func (b *Bot) Delete(message Editable) error {
return extractOkResponse(respJSON)
}
// Action updates a chat action for recipient.
// Notify updates the chat action for recipient.
//
// Chat action is a status message that recipient would see where
// you typically see "Harry is typing" status message. The only
@ -359,7 +359,7 @@ func (b *Bot) Delete(message Editable) error {
//
// Currently, Telegram supports only a narrow range of possible
// actions, these are aligned as constants of this package.
func (b *Bot) Action(recipient Recipient, action ChatAction) error {
func (b *Bot) Notify(recipient Recipient, action ChatAction) error {
params := map[string]string{
"chat_id": recipient.Recipient(),
"action": string(action),
@ -373,12 +373,10 @@ func (b *Bot) Action(recipient Recipient, action ChatAction) error {
return extractOkResponse(respJSON)
}
// AnswerInlineQuery sends a response for a given inline query. A query can
// only be responded to once, subsequent attempts to respond to the same query
// Answer sends a response for a given inline query. A query can only
// be responded to once, subsequent attempts to respond to the same query
// will result in an error.
func (b *Bot) AnswerInlineQuery(query *Query, response *QueryResponse) error {
response.QueryID = query.ID
func (b *Bot) Answer(query *Query, response *QueryResponse) error {
respJSON, err := b.sendCommand("answerInlineQuery", response)
if err != nil {
return err
@ -387,10 +385,10 @@ func (b *Bot) AnswerInlineQuery(query *Query, response *QueryResponse) error {
return extractOkResponse(respJSON)
}
// AnswerCallbackQuery sends a response for a given callback query. A callback can
// Respond sends a response for a given callback query. A callback can
// only be responded to once, subsequent attempts to respond to the same callback
// will result in an error.
func (b *Bot) AnswerCallbackQuery(callback *Callback, response *CallbackResponse) error {
func (b *Bot) Respond(callback *Callback, response *CallbackResponse) error {
response.CallbackID = callback.ID
respJSON, err := b.sendCommand("answerCallbackQuery", response)

@ -26,10 +26,12 @@ type Callback struct {
// See also: https://core.telegram.org/bots/api#answerCallbackQuery
type CallbackResponse struct {
// The ID of the callback to which this is a response.
// It is not necessary to specify this field manually.
//
// Note: Telebot sets this field automatically!
CallbackID string `json:"callback_query_id"`
// Text of the notification. If not specified, nothing will be shown to the user.
// Text of the notification. If not specified, nothing will be
// shown to the user.
Text string `json:"text,omitempty"`
// (Optional) If true, an alert will be shown by the client instead
@ -37,9 +39,11 @@ type CallbackResponse struct {
ShowAlert bool `json:"show_alert,omitempty"`
// (Optional) URL that will be opened by the user's client.
// If you have created a Game and accepted the conditions via @Botfather
// specify the URL that opens your game
// note that this will only work if the query comes from a callback_game button.
// Otherwise, you may use links like telegram.me/your_bot?start=XXXX that open your bot with a parameter.
// If you have created a Game and accepted the conditions via
// @BotFather, specify the URL that opens your game.
//
// Note: this will only work if the query comes from a game
// callback button. Otherwise, you may use deep-linking:
// https://telegram.me/your_bot?start=XXXX
URL string `json:"url,omitempty"`
}

@ -7,6 +7,7 @@ import (
"strconv"
"github.com/mitchellh/hashstructure"
"github.com/pkg/errors"
)
// inlineQueryHashOptions sets the HashOptions to be used when hashing
@ -39,11 +40,12 @@ type Query struct {
// See also: https://core.telegram.org/bots/api#answerinlinequery
type QueryResponse struct {
// The ID of the query to which this is a response.
// It is not necessary to specify this field manually.
//
// Note: Telebot sets this field automatically!
QueryID string `json:"inline_query_id"`
// The results for the inline query.
Results InlineQueryResults `json:"results"`
Results Results `json:"results"`
// (Optional) The maximum amount of time in seconds that the result
// of the inline query may be cached on the server.
@ -70,66 +72,64 @@ type QueryResponse struct {
SwitchPMParameter string `json:"switch_pm_parameter,omitempty"`
}
// InlineQueryResult represents one result of an inline query.
type InlineQueryResult interface {
GetID() string
SetID(string)
// Result represents one result of an inline query.
type Result interface {
ResultID() string
SetResultID(string)
}
// InlineQueryResults is a slice wrapper for convenient marshalling.
type InlineQueryResults []InlineQueryResult
// Results is a slice wrapper for convenient marshalling.
type Results []Result
// MarshalJSON makes sure IQRs have proper IDs and Type variables set.
//
// If ID of some result appears empty, it gets set to a new hash.
// JSON-specific Type gets infered from the actual (specific) IQR type.
func (results InlineQueryResults) MarshalJSON() ([]byte, error) {
for i, result := range results {
if result.GetID() == "" {
func (results Results) MarshalJSON() ([]byte, error) {
for _, result := range results {
if result.ResultID() == "" {
hash, err := hashstructure.Hash(result, inlineQueryHashOptions)
if err != nil {
return nil, fmt.Errorf("telebot: can't hash IQR #%d: %s",
i, err)
return nil, errors.Wrap(err, "telebot: can't hash the result")
}
result.SetID(strconv.FormatUint(hash, 16))
result.SetResultID(strconv.FormatUint(hash, 16))
}
if err := inferIQR(result); err != nil {
return nil, fmt.Errorf("telebot: can't infer type of IQR #%d: %s",
i, err)
return nil, err
}
}
return json.Marshal([]InlineQueryResult(results))
return json.Marshal(results)
}
func inferIQR(result InlineQueryResult) error {
func inferIQR(result Result) error {
switch r := result.(type) {
case *InlineQueryResultArticle:
case *ArticleResult:
r.Type = "article"
case *InlineQueryResultAudio:
case *AudioResult:
r.Type = "audio"
case *InlineQueryResultContact:
case *ContactResult:
r.Type = "contact"
case *InlineQueryResultDocument:
case *DocumentResult:
r.Type = "document"
case *InlineQueryResultGif:
case *GifResult:
r.Type = "gif"
case *InlineQueryResultLocation:
case *LocationResult:
r.Type = "location"
case *InlineQueryResultMpeg4Gif:
case *Mpeg4GifResult:
r.Type = "mpeg4_gif"
case *InlineQueryResultPhoto:
case *PhotoResult:
r.Type = "photo"
case *InlineQueryResultVenue:
case *VenueResult:
r.Type = "venue"
case *InlineQueryResultVideo:
case *VideoResult:
r.Type = "video"
case *InlineQueryResultVoice:
case *VoiceResult:
r.Type = "voice"
default:
return fmt.Errorf("%T is not an IQR", result)
return fmt.Errorf("result %v is not supported", result)
}
return nil

@ -1,30 +1,35 @@
package telebot
// InlineQueryResultBase must be embedded into all IQRs.
type InlineQueryResultBase struct {
// ResultBase must be embedded into all IQRs.
type ResultBase struct {
// Unique identifier for this result, 1-64 Bytes.
// If left unspecified, a 64-bit FNV-1 hash will be calculated
// from the other fields and used automatically.
ID string `json:"id",hash:"ignore"`
// Ignore. This field gets set automatically.
Type string `json:"type",hash:"ignore"`
// Content of the message to be sent.
Content *InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
}
// GetID is part of IQRBase's implementation of IQR interface.
func (result *InlineQueryResultBase) GetID() string {
return result.ID
// ResultID returns ResultBase.ID.
func (r *ResultBase) ResultID() string {
return r.ID
}
// SetID is part of IQRBase's implementation of IQR interface.
func (result *InlineQueryResultBase) SetID(id string) {
result.ID = id
// SetResultID sets ResultBase.ID.
func (r *ResultBase) SetResultID(id string) {
r.ID = id
}
// InlineQueryResultArticle represents a link to an article or web page.
// ArticleResult represents a link to an article or web page.
// See also: https://core.telegram.org/bots/api#inlinequeryresultarticle
type InlineQueryResultArticle struct {
InlineQueryResultBase
type ArticleResult struct {
ResultBase
// Title of the result.
Title string `json:"title"`
@ -33,12 +38,6 @@ type InlineQueryResultArticle struct {
// InputMessageContent.
Text string `json:"message_text,omitempty"`
// Content of the message to be sent.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. URL of the result.
URL string `json:"url,omitempty"`
@ -48,43 +47,31 @@ type InlineQueryResultArticle struct {
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. Url of the thumbnail for the result.
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Thumbnail width.
ThumbWidth int `json:"thumb_width,omitempty"`
// Optional. Thumbnail height.
ThumbHeight int `json:"thumb_height,omitempty"`
}
// InlineQueryResultAudio represents a link to an mp3 audio file.
type InlineQueryResultAudio struct {
InlineQueryResultBase
// A valid URL for the audio file.
AudioURL string `json:"audio_url"`
// AudioResult represents a link to an mp3 audio file.
type AudioResult struct {
ResultBase
// Title.
Title string `json:"title"`
// A valid URL for the audio file.
URL string `json:"audio_url"`
// Optional. Performer.
Performer string `json:"performer,omitempty"`
// Optional. Audio duration in seconds.
Duration int `json:"audio_duration,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
}
// InlineQueryResultContact represents a contact with a phone number.
// ContentResult represents a contact with a phone number.
// See also: https://core.telegram.org/bots/api#inlinequeryresultcontact
type InlineQueryResultContact struct {
InlineQueryResultBase
type ContactResult struct {
ResultBase
// Contact's phone number.
PhoneNumber string `json:"phone_number"`
@ -95,36 +82,24 @@ type InlineQueryResultContact struct {
// Optional. Contact's last name.
LastName string `json:"last_name,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Url of the thumbnail for the result.
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Thumbnail width.
ThumbWidth int `json:"thumb_width,omitempty"`
// Optional. Thumbnail height.
ThumbHeight int `json:"thumb_height,omitempty"`
}
// InlineQueryResultDocument represents a link to a file.
// DocumentResult represents a link to a file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultdocument
type InlineQueryResultDocument struct {
InlineQueryResultBase
type DocumentResult struct {
ResultBase
// Title for the result.
Title string `json:"title"`
// A valid URL for the file
DocumentURL string `json:"document_url"`
URL string `json:"document_url"`
// Mime type of the content of the file, either “application/pdf” or
// “application/zip”.
MimeType string `json:"mime_type"`
MIME string `json:"mime_type"`
// Optional. Caption of the document to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
@ -132,38 +107,23 @@ type InlineQueryResultDocument struct {
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// Optional. URL of the thumbnail (jpeg only) for the file.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Thumbnail width.
ThumbWidth int `json:"thumb_width,omitempty"`
// Optional. Thumbnail height.
ThumbHeight int `json:"thumb_height,omitempty"`
}
// InlineQueryResultGif represents a link to an animated GIF file.
// GifResult represents a link to an animated GIF file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultgif
type InlineQueryResultGif struct {
InlineQueryResultBase
type GifResult struct {
ResultBase
// A valid URL for the GIF file. File size must not exceed 1MB.
GifURL string `json:"gif_url"`
// URL of the static thumbnail for the result (jpeg or gif).
ThumbURL string `json:"thumb_url"`
URL string `json:"gif_url"`
// Optional. Width of the GIF.
GifWidth int `json:"gif_width,omitempty"`
Width int `json:"gif_width,omitempty"`
// Optional. Height of the GIF.
GifHeight int `json:"gif_height,omitempty"`
Height int `json:"gif_height,omitempty"`
// Optional. Title for the result.
Title string `json:"title,omitempty"`
@ -171,48 +131,29 @@ type InlineQueryResultGif struct {
// Optional. Caption of the GIF file to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// URL of the static thumbnail for the result (jpeg or gif).
ThumbURL string `json:"thumb_url"`
}
// InlineQueryResultLocation represents a location on a map.
// LocationResult represents a location on a map.
// See also: https://core.telegram.org/bots/api#inlinequeryresultlocation
type InlineQueryResultLocation struct {
InlineQueryResultBase
// Latitude of the location in degrees.
Latitude float32 `json:"latitude"`
type LocationResult struct {
ResultBase
// Longitude of the location in degrees.
Longitude float32 `json:"longitude"`
Location
// Location title.
Title string `json:"title"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Url of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Thumbnail width.
ThumbWidth int `json:"thumb_width,omitempty"`
// Optional. Thumbnail height.
ThumbHeight int `json:"thumb_height,omitempty"`
}
// InlineQueryResultMpeg4Gif represents a link to a video animation
// ResultMpeg4Gif represents a link to a video animation
// (H.264/MPEG-4 AVC video without sound).
// See also: https://core.telegram.org/bots/api#inlinequeryresultmpeg4gif
type InlineQueryResultMpeg4Gif struct {
InlineQueryResultBase
type Mpeg4GifResult struct {
ResultBase
// A valid URL for the MP4 file.
URL string `json:"mpeg4_url"`
@ -231,31 +172,22 @@ type InlineQueryResultMpeg4Gif struct {
// Optional. Caption of the MPEG-4 file to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
}
// InlineQueryResultPhoto represents a link to a photo.
// ResultResult represents a link to a photo.
// See also: https://core.telegram.org/bots/api#inlinequeryresultphoto
type InlineQueryResultPhoto struct {
InlineQueryResultBase
type PhotoResult struct {
ResultBase
// A valid URL of the photo. Photo must be in jpeg format.
// Photo size must not exceed 5MB.
PhotoURL string `json:"photo_url"`
// URL of the thumbnail for the photo.
ThumbURL string `json:"thumb_url"`
URL string `json:"photo_url"`
// Optional. Width of the photo.
PhotoWidth int `json:"photo_width,omitempty"`
Width int `json:"photo_width,omitempty"`
// Optional. Height of the photo.
PhotoHeight int `json:"photo_height,omitempty"`
Height int `json:"photo_height,omitempty"`
// Optional. Title for the result.
Title string `json:"title,omitempty"`
@ -266,23 +198,16 @@ type InlineQueryResultPhoto struct {
// Optional. Caption of the photo to be sent, 0-200 characters.
Caption string `json:"caption,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// URL of the thumbnail for the photo.
ThumbURL string `json:"thumb_url"`
}
// InlineQueryResultVenue represents a venue.
// VenueResult represents a venue.
// See also: https://core.telegram.org/bots/api#inlinequeryresultvenue
type InlineQueryResultVenue struct {
InlineQueryResultBase
// Latitude of the venue location in degrees.
Latitude float32 `json:"latitude"`
type VenueResult struct {
ResultBase
// Longitude of the venue location in degrees.
Longitude float32 `json:"longitude"`
Location
// Title of the venue.
Title string `json:"title"`
@ -293,33 +218,21 @@ type InlineQueryResultVenue struct {
// Optional. Foursquare identifier of the venue if known.
FoursquareID string `json:"foursquare_id,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
// Optional. Url of the thumbnail for the result.
// Optional. URL of the thumbnail for the result.
ThumbURL string `json:"thumb_url,omitempty"`
// Optional. Thumbnail width.
ThumbWidth int `json:"thumb_width,omitempty"`
// Optional. Thumbnail height.
ThumbHeight int `json:"thumb_height,omitempty"`
}
// InlineQueryResultVideo represents a link to a page containing an embedded
// VideoResult represents a link to a page containing an embedded
// video player or a video file.
// See also: https://core.telegram.org/bots/api#inlinequeryresultvideo
type InlineQueryResultVideo struct {
InlineQueryResultBase
type VideoResult struct {
ResultBase
// A valid URL for the embedded video player or video file.
VideoURL string `json:"video_url"`
URL string `json:"video_url"`
// Mime type of the content of video url, “text/html” or “video/mp4”.
MimeType string `json:"mime_type"`
MIME string `json:"mime_type"`
// URL of the thumbnail (jpeg only) for the video.
ThumbURL string `json:"thumb_url"`
@ -331,42 +244,31 @@ type InlineQueryResultVideo struct {
Caption string `json:"caption,omitempty"`
// Optional. Video width.
VideoWidth int `json:"video_width,omitempty"`
Width int `json:"video_width,omitempty"`
// Optional. Video height.
VideoHeight int `json:"video_height,omitempty"`
Height int `json:"video_height,omitempty"`
// Optional. Video duration in seconds.
VideoDuration int `json:"video_duration,omitempty"`
Duration int `json:"video_duration,omitempty"`
// Optional. Short description of the result.
Description string `json:"description,omitempty"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
}
// InlineQueryResultVoice represents a link to a voice recording in a
// .ogg container encoded with OPUS.
// VoiceResult represents a link to a voice recording in an .ogg
// container encoded with OPUS.
//
// See also: https://core.telegram.org/bots/api#inlinequeryresultvoice
type InlineQueryResultVoice struct {
InlineQueryResultBase
type VoiceResult struct {
ResultBase
// A valid URL for the voice recording.
VoiceURL string `json:"voice_url"`
URL string `json:"voice_url"`
// Recording title.
Title string `json:"title"`
// Optional. Recording duration in seconds.
VoiceDuration int `json:"voice_duration"`
// Optional. Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"`
// Optional. Content of the message to be sent instead of the audio.
InputMessageContent InputMessageContent `json:"input_message_content,omitempty"`
Duration int `json:"voice_duration"`
}

Loading…
Cancel
Save