diff --git a/bot_test.go b/bot_test.go index 5d4beb5..3d8e97a 100644 --- a/bot_test.go +++ b/bot_test.go @@ -848,11 +848,21 @@ func (s *BotTestSuite) TestGetGameHighScorese() { s.Equal(len(scores), 2) s.Equal(scores[0].Position, 1) s.Equal(scores[0].Score, 22) - s.Equal(scores[0].User, User{456, "John", "Doe", "john_doe", ""}) + s.Equal(scores[0].User, User{ + ID: 456, + FirstName: "John", + LastName: "Doe", + Username: "john_doe", + }) s.Equal(scores[1].Position, 2) s.Equal(scores[1].Score, 11) - s.Equal(scores[1].User, User{789, "Mohammad", "Li", "mli", ""}) + s.Equal(scores[1].User, User{ + ID: 789, + FirstName: "Mohammad", + LastName: "Li", + Username: "mli", + }) } diff --git a/go.mod b/go.mod index 81db09a..1099612 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/onrik/micha go 1.13 + +require ( + github.com/jarcoal/httpmock v1.0.4 + github.com/stretchr/testify v1.4.0 +) diff --git a/options.go b/options.go index 57ca043..ee0f53d 100644 --- a/options.go +++ b/options.go @@ -39,36 +39,42 @@ func WithHttpClient(httpClient HttpClient) Option { } } -// Send message optional params +// SendMessageOptions optional params SendMessage method type SendMessageOptions struct { - DisableNotification bool `json:"disable_notification,omitempty"` - ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ParseMode ParseMode `json:"parse_mode,omitempty"` DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send photo optional params +// SendPhotoOptions optional params SendPhoto method type SendPhotoOptions struct { Caption string `json:"caption,omitempty"` + ParseMode ParseMode `json:"parse_mode,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send audio optional params +// SendAudioOptions optional params SendAudio method type SendAudioOptions struct { + Caption string `json:"caption,omitempty"` + ParseMode ParseMode `json:"parse_mode,omitempty"` Duration int `json:"duration,omitempty"` Performer string `json:"performer,omitempty"` Title string `json:"title,omitempty"` + Thumb string `json:"thumb,omitempty"` // TODO add thumb as file DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send document optional params +// SendDocumentOptions optional params SendDocument method type SendDocumentOptions struct { + Thumb string `json:"thumb,omitempty"` // TODO add thumb as file Caption string `json:"caption,omitempty"` + ParseMode ParseMode `json:"parse_mode,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` @@ -81,57 +87,66 @@ type SendStickerOptions struct { ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send video optional params +// SendVideoOptions video optional params SendVideo method type SendVideoOptions struct { Duration int `json:"duration,omitempty"` Width int `json:"width,omitempty"` Height int `json:"height,omitempty"` + Thumb string `json:"thumb,omitempty"` // TODO add thumb as file Caption string `json:"caption,omitempty"` + ParseMode ParseMode `json:"parse_mode,omitempty"` + SupportsStreaming bool `json:"supports_streaming,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send voice optional params +// SendVoiceOptions optional params for SendVoice method type SendVoiceOptions struct { + Caption string `json:"caption,omitempty"` + ParseMode ParseMode `json:"parse_mode,omitempty"` Duration int `json:"duration,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send video note optional params +// SendVideoNoteOptions optional params for SendVideoNote method type SendVideoNoteOptions struct { Duration int `json:"duration,omitempty"` Length int `json:"length,omitempty"` + Thumb string `json:"thumb,omitempty"` // TODO add thumb as file DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send location optional params +// SendLocationOptions optional params for SendLocation method type SendLocationOptions struct { + LivePeriod int `json:"live_period,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send venue optional params +// SendVenueOptions optional params for SendVenue method type SendVenueOptions struct { FoursquareID string `json:"foursquare_id,omitempty"` + FoursquareType string `json:"foursquare_type,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send contact optional params +// SendContactOptions optional params for SendContact method type SendContactOptions struct { + VCard string `json:"vcard,omitempty"` DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } -// Send game optional params +// SendGameOptions optional params for SendGame method type SendGameOptions struct { DisableNotification bool `json:"disable_notification,omitempty"` ReplyToMessageID int64 `json:"reply_to_message_id,omitempty"` diff --git a/types.go b/types.go index 9c0493d..9f00ca9 100644 --- a/types.go +++ b/types.go @@ -49,6 +49,7 @@ type MessageEntityType string // User object represents a Telegram user, bot type User struct { ID int64 `json:"id"` + IsBot bool `json:"is_bot"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Username string `json:"username"` @@ -62,105 +63,181 @@ func (chatID *ChatID) UnmarshalJSON(value []byte) error { return nil } -// Chat object represents a Telegram user, bot or group chat. +// Chat object represents a chat. type Chat struct { - ID ChatID `json:"id"` - Type ChatType `json:"type"` - Title string `json:"title"` - FirstName string `json:"first_name"` - LastName string `json:"last_name"` - Username string `json:"username"` -} + ID ChatID `json:"id"` + Type ChatType `json:"type"` -type ChatMember struct { - User User `json:"user"` - Status MemberStatus `json:"status"` + // Optional + Title string `json:"title,omitempty"` + Username string `json:"username,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + Photo *ChatPhoto `json:"photo,omitempty"` + Description string `json:"description,omitempty"` + InviteLink string `json:"invite_link,omitempty"` + PinnedMessage *Message `json:"pinned_message,omitempty"` + Permissions *ChatPermissions `json:"permissions,omitempty"` + StickerSetName string `json:"sticker_set_name,omitempty"` + CanSetStickerSet bool `json:"can_set_sticker_set,omitempty"` } -type FileBase struct { - FileID string `json:"file_id"` - FileSize uint64 `json:"file_size"` -} +// Message object represents a message. +type Message struct { + MessageID int64 `json:"message_id"` + From User `json:"from"` + Date uint64 `json:"date"` + Chat Chat `json:"chat"` -// Thumbnail object represents an image/sticker of a particular size. -type PhotoSize struct { - FileBase + // Optional + ForwardFrom *User `json:"forward_from,omitempty"` + ForwardFromChat *Chat `json:"forward_from_chat,omitempty"` + ForwardFromMessageID int64 `json:"forward_from_message_id,omitempty"` + ForwardSignature string `json:"forward_signature,omitempty"` + ForwardSenderName string `json:"forward_sender_name,omitempty"` + ForwardDate uint64 `json:"forward_date,omitempty"` + ReplyToMessage *Message `json:"reply_to_message,omitempty"` + EditDate uint64 `json:"edit_date,omitempty"` + MediaGroupID string `json:"media_group_id,omitempty"` + AuthorSignature string `json:"author_signature,omitempty"` + Text string `json:"text,omitempty"` + Entities []MessageEntity `json:"entities,omitempty"` + CaptionEntities []MessageEntity `json:"caption_entities,omitempty"` + Audio *Audio `json:"audio,omitempty"` + Document *Document `json:"document,omitempty"` + Animation *Animation `json:"animation,omitempty"` + Game *Game `json:"game,omitempty"` + Photo []PhotoSize `json:"photo,omitempty"` + Sticker *Sticker `json:"sticker,omitempty"` + Video *Video `json:"video,omitempty"` + Voice *Voice `json:"voice,omitempty"` + VideoNote *VideoNote `json:"video_note,omitempty"` + Caption string `json:"caption,omitempty"` + Contact *Contact `json:"contact,omitempty"` + Location *Location `json:"location,omitempty"` + Venue *Venue `json:"venue,omitempty"` + Poll *Poll `json:"poll,omitempty"` + NewChatMembers []User `json:"new_chat_members,omitempty"` + LeftChatMember *User `json:"left_chat_member,omitempty"` + NewChatTitle string `json:"new_chat_title,omitempty"` + NewChatPhoto []PhotoSize `json:"new_chat_photo,omitempty"` + DeleteChatPhoto bool `json:"delete_chat_photo,omitempty"` + GroupChatCreated bool `json:"group_chat_created,omitempty"` + SupergroupChatCreated bool `json:"supergroup_chat_created,omitempty"` + ChannelChatCreated bool `json:"channel_chat_created,omitempty"` + MigrateToChatID ChatID `json:"migrate_to_chat_id,omitempty"` + MigrateFromChatID ChatID `json:"migrate_from_chat_id,omitempty"` + PinnedMessage *Message `json:"pinned_message,omitempty"` + Invoice *Invoice `json:"invoice,omitempty"` + SuccessfulPayment *SuccessfulPayment `json:"successful_payment,omitempty"` + ConnectedWebsite string `json:"connected_website,omitempty"` + PassportData *PassportData `json:"passport_data,omitempty"` + ReplyMarkup InlineKeyboardMarkup `json:"reply_markup,omitempty"` +} + +// MessageEntity object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc. +type MessageEntity struct { + Type MessageEntityType `json:"type"` + Offset int `json:"offset"` + Limit int `json:"limit"` - Width int `json:"width"` - Height int `json:"height"` + // Optional + URL string `json:"url,omitempty"` // For “text_link” only, url that will be opened after user taps on the text + User *User `json:"user,omitempty"` // For “text_mention” only, the mentioned user } -// Photo object represents a photo with caption. -type Photo struct { - FileBase - PhotoSize +// PhotoSize object represents an image/sticker of a particular size. +type PhotoSize struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` - Caption string `json:"caption"` + // Optional + FileSize uint64 `json:"file_size,omitempty"` } // Audio object represents an audio file (voice note). type Audio struct { - FileBase + FileID string `json:"file_id"` + Duration int `json:"duration"` - Duration int `json:"duration"` - MimeType string `json:"mime_type"` - Performer string `json:"performer"` - Title string `json:"title"` + // Optional + Performer string `json:"performer,omitempty"` + Title string `json:"title,omitempty"` + MimeType string `json:"mime_type,omitempty"` + Thumb *PhotoSize `json:"thumb,omitempty"` + FileSize uint64 `json:"file_size,omitempty"` } // Document object represents a general file (as opposed to Photo or Audio). // Telegram users can send files of any type of up to 1.5 GB in size. type Document struct { - FileBase - - Thumb *PhotoSize `json:"thumb"` - FileName string `json:"file_name"` - MimeType string `json:"mime_type"` -} - -// Sticker object represents a WebP image, so-called sticker. -type Sticker struct { - FileBase + FileID string `json:"file_id"` - Width int `json:"width"` - Height int `json:"height"` - Thumb *PhotoSize `json:"thumb"` - Emoji string `json:"emoji"` + // Optional + Thumb *PhotoSize `json:"thumb,omitempty"` + FileName string `json:"file_name,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize uint64 `json:"file_size,omitempty"` } // Video object represents an MP4-encoded video. type Video struct { - FileBase + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Duration int `json:"duration"` - Duration int `json:"duration"` - Width int `json:"width"` - Height int `json:"height"` - Thumb *PhotoSize `json:"thumb"` + // Optional + Thumb *PhotoSize `json:"thumb,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize uint64 `json:"file_size,omitempty"` } -// VideoNote object represents a video message. -type VideoNote struct { - FileBase +// Animation object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound). +type Animation struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Duration int `json:"duration"` - Length int `json:"length"` - Duration int `json:"duration"` - Thumb PhotoSize `json:"thumb"` + // Optional + Thumb *PhotoSize `json:"thumb,omitempty"` + FileName string `json:"file_name,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize *int `json:"file_size,omitempty"` } // Voice object represents a voice note. type Voice struct { FileID string `json:"file_id"` Duration int `json:"duration"` - MimeType string `json:"mime_type"` - FileSize int `json:"file_size"` + + // Optional + MimeType string `json:"mime_type,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +// VideoNote object represents a video message. +type VideoNote struct { + FileID string `json:"file_id"` + Length int `json:"length"` + Duration int `json:"duration"` + + // Optional + Thumb *PhotoSize `json:"thumb,omitempty"` + FileSize int `json:"file_size,omitempty"` } // Contact object represents a contact to Telegram user type Contact struct { - UserID int64 `json:"user_id"` PhoneNumber string `json:"phone_number"` FirstName string `json:"first_name"` - LastName string `json:"last_name"` + + // Optional + LastName string `json:"last_name,omitempty"` + UserID int64 `json:"user_id,omitempty"` + VCard string `json:"vcard,omitempty"` } // Location object represents geographic position. @@ -171,104 +248,45 @@ type Location struct { // Venue object represents a venue. type Venue struct { - Location Location `json:"location"` - Title string `json:"title"` - Address string `json:"address"` - FoursquareID string `json:"foursquare_id"` -} - -type UserProfilePhotos struct { - TotalCount int `json:"total_count"` - Photos [][]PhotoSize `json:"photos"` -} - -type File struct { - FileBase - FilePath string `json:"file_path"` -} - -type MessageEntity struct { - Type MessageEntityType `json:"type"` - Offset int `json:"offset"` - Limit int `json:"limit"` + Location Location `json:"location"` + Title string `json:"title"` + Address string `json:"address"` // Optional - URL string `json:"url"` // For “text_link” only, url that will be opened after user taps on the text - User *User `json:"user"` // For “text_mention” only, the mentioned user + FoursquareID string `json:"foursquare_id,omitempty"` + FoursquareType string `json:"foursquare_type,omitempty"` } -// You can provide an animation for your game so that it looks stylish in chats. -// This object represents an animation file to be displayed in the message containing a game. -type Animation struct { - FileID string `json:"file_id"` - - // Optional - Thumb *PhotoSize `json:"thumb"` - FileName string `json:"file_name"` - MimeType string `json:"mime_type"` - FileSize *int `json:"file_size"` +// PollOption object contains information about one answer option in a poll. +type PollOption struct { + Text string `json:"text"` + VoterCount int `json:"voter_count"` } -// This object represents a game. -// Use BotFather to create and edit games, their short names will act as unique identifiers. -type Game struct { - Title string `json:"title"` - Description string `json:"description"` - Photo []PhotoSize `json:"photo"` - - // Optional - Text string `json:"text"` - TextEntities []MessageEntity `json:"text_entities"` - Animation *Animation `json:"animation"` +// Poll object contains information about a poll. +type Poll struct { + ID string `json:"id"` + Question string `json:"question"` + Options []PollOption `json:"options"` + IsClosed bool `json:"is_closed"` } -// This object represents one row of the high scores table for a game. -type GameHighScore struct { - Position int `json:"position"` - User User `json:"user"` - Score int `json:"score"` +// UserProfilePhotos object represent a user's profile pictures. +type UserProfilePhotos struct { + TotalCount int `json:"total_count"` + Photos [][]PhotoSize `json:"photos"` } -// Message object represents a message. -type Message struct { - MessageID int64 `json:"message_id"` - From User `json:"from"` - Date uint64 `json:"date"` - Chat Chat `json:"chat"` +// File object represents a file ready to be downloaded. +// The file can be downloaded via the link https://api.telegram.org/file/bot/. +// It is guaranteed that the link will be valid for at least 1 hour. +// When the link expires, a new one can be requested by calling getFile. +type File struct { + FileID string `json:"file_id"` // Optional - ForwardFrom *User `json:"forward_from"` - ForwardFromChat *Chat `json:"forward_from_chat"` - ForwardFromMessageID int64 `json:"forward_from_message_id"` - ForwardDate uint64 `json:"forward_date"` - ReplyToMessage *Message `json:"reply_to_message"` - EditDate uint64 `json:"edit_date"` - Text string `json:"text"` - Entities []MessageEntity `json:"entities"` - Audio *Audio `json:"audio"` - Document *Document `json:"document"` - Game *Game `json:"game"` - Photo []PhotoSize `json:"photo"` - Sticker *Sticker `json:"sticker"` - Video *Video `json:"video"` - VideoNote *VideoNote `json:"video_note"` - NewChatMembers []User `json:"new_chat_members"` - Voice *Voice `json:"voice"` - Caption string `json:"caption"` - Contact *Contact `json:"contact"` - Location *Location `json:"location"` - Venue *Venue `json:"venue"` - NewChatMember *User `json:"new_chat_member"` - LeftChatMember *User `json:"left_chat_member"` - NewChatTitle string `json:"new_chat_title"` - NewChatPhoto []PhotoSize `json:"new_chat_photo"` - DeleteChatPhoto bool `json:"delete_chat_photo"` - GroupChatCreated bool `json:"group_chat_created"` - SupergroupChatCreated bool `json:"supergroup_chat_created"` - ChannelChatCreated bool `json:"channel_chat_created"` - MigrateToChatID ChatID `json:"migrate_to_chat_id"` - MigrateFromChatID ChatID `json:"migrate_from_chat_id"` - PinnedMessage *Message `json:"pinned_message"` + FileSize uint64 `json:"file_size,omitempty"` + FilePath string `json:"file_path,omitempty"` } type ReplyMarkup interface { @@ -279,7 +297,7 @@ type replyMarkupImplementation struct{} func (r replyMarkupImplementation) itsReplyMarkup() {} -// This object represents one button of the reply keyboard. +// KeyboardButton object represents one button of the reply keyboard. // For simple text buttons String can be used instead of this object to specify text of the button. // Optional fields are mutually exclusive. type KeyboardButton struct { @@ -290,7 +308,7 @@ type KeyboardButton struct { RequestLocation bool `json:"request_location,omitempty"` } -// This object represents a custom keyboard with reply options +// ReplyKeyboardMarkup object represents a custom keyboard with reply options type ReplyKeyboardMarkup struct { replyMarkupImplementation Keyboard [][]KeyboardButton `json:"keyboard"` @@ -299,8 +317,8 @@ type ReplyKeyboardMarkup struct { Selective bool `json:"selective,omitempty"` } -// Upon receiving a message with this object, -// Telegram clients will remove the current custom keyboard and display the default letter-keyboard. +// ReplyKeyboardRemove object +// Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display the default letter-keyboard. // By default, custom keyboards are displayed until a new keyboard is sent by a bot. // An exception is made for one-time keyboards that are hidden immediately after the user presses a button type ReplyKeyboardRemove struct { @@ -309,34 +327,38 @@ type ReplyKeyboardRemove struct { Selective bool `json:"selective,omitempty"` } -// This object represents one button of an inline keyboard. You must use exactly one of the optional fields. +// InlineKeyboardButton object represents one button of an inline keyboard. You must use exactly one of the optional fields. type InlineKeyboardButton struct { Text string `json:"text,omitempty"` // Optional - URL string `json:"url,omitempty"` - CallbackData string `json:"callback_data,omitempty"` - SwitchInlineQuery string `json:"switch_inline_query,omitempty"` - SwitchInlineQueryCurrentChat string `json:"switch_inline_query_current_chat,omitempty"` - Pay bool `json:"pay,omitempty"` + URL string `json:"url,omitempty"` + LoginURL *LoginURL `json:"login_url,omitempty"` + CallbackData string `json:"callback_data,omitempty"` + SwitchInlineQuery string `json:"switch_inline_query,omitempty"` + SwitchInlineQueryCurrentChat string `json:"switch_inline_query_current_chat,omitempty"` + Pay bool `json:"pay,omitempty"` } -// This object represents an inline keyboard that appears right next to the message it belongs to. -type InlineKeyboardMarkup struct { - replyMarkupImplementation - InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"` +// LoginURL object represents a parameter of the inline keyboard button used to automatically authorize a user. +// Serves as a great replacement for the Telegram Login Widget when the user is coming from Telegram. +// All the user needs to do is tap/click a button and confirm that they want to log in: +type LoginURL struct { + URL string `json:"url"` + + // Optional + ForwardText string `json:"forward_text,omitempty"` + BotUsername string `json:"bot_username,omitempty"` + RequestWriteAccess bool `json:"request_write_access,omitempty"` } -// Upon receiving a message with this object, -// Telegram clients will display a reply interface to the user. -// This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. -type ForceReply struct { +// InlineKeyboardMarkup object represents an inline keyboard that appears right next to the message it belongs to. +type InlineKeyboardMarkup struct { replyMarkupImplementation - ForceReply bool `json:"force_reply"` - Selective bool `json:"selective,omitempty"` + InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"` } -// Represents a result of an inline query that was chosen by the user and sent to their chat partner. +// ChosenInlineResult object represents a result of an inline query that was chosen by the user and sent to their chat partner. type ChosenInlineResult struct { ResultID string `json:"result_id"` From User `json:"from"` @@ -345,60 +367,104 @@ type ChosenInlineResult struct { Query string `json:"query"` } -// This object represents an incoming callback query from a callback button in an inline keyboard. +// CallbackQuery object represents an incoming callback query from a callback button in an inline keyboard. // If the button that originated the query was attached to a message sent by the bot, the field message will be presented. // If the button was attached to a message sent via the bot (in inline mode), the field inline_message_id will be presented. type CallbackQuery struct { - ID string `json:"id"` - From User `json:"from"` - Message *Message `json:"message"` - InlineMessageID string `json:"inline_message_id"` - ChatInstance string `json:"chat_instance"` - Data string `json:"data"` - GameShortName string `json:"game_short_name"` + ID string `json:"id"` + From User `json:"from"` + + // Optional + Message *Message `json:"message,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + ChatInstance string `json:"chat_instance,omitempty"` + Data string `json:"data,omitempty"` + GameShortName string `json:"game_short_name,omitempty"` } -// This object represents an incoming inline query. -// When the user sends an empty query, your bot could return some default or trending results. -type InlineQuery struct { - ID string `json:"id"` - From User `json:"from"` - Query string `json:"query"` - Offset string `json:"offset"` +// ForceReply object +// Upon receiving a message with this object, +// Telegram clients will display a reply interface to the user. +// This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. +type ForceReply struct { + replyMarkupImplementation + ForceReply bool `json:"force_reply"` + Selective bool `json:"selective,omitempty"` +} + +// ChatPhoto object represents a chat photo. +type ChatPhoto struct { + SmallFileID string `json:"small_file_id"` + BigFileID string `json:"big_file_id"` } -// This object represents an incoming update. +// ChatMember object contains information about one member of a chat. +type ChatMember struct { + User User `json:"user"` + Status MemberStatus `json:"status"` + + // Optional + UntilDate int64 `json:"until_date,omitempty"` + CanBeEdited bool `json:"can_be_edited,omitempty"` + CanPostMessages bool `json:"can_post_messages,omitempty"` + CanEditMessages bool `json:"can_edit_messages,omitempty"` + CanDeleteMessages bool `json:"can_delete_messages,omitempty"` + CanRestrictMembers bool `json:"can_restrict_members,omitempty"` + CanPromoteMembers bool `json:"can_promote_members,omitempty"` + CanChangeInfo bool `json:"can_change_info,omitempty"` + CanInviteUsers bool `json:"can_invite_users,omitempty"` + CanPinMessages bool `json:"can_pin_messages,omitempty"` + IsMember bool `json:"is_member,omitempty"` + CanSendMessages bool `json:"can_send_messages,omitempty"` + CanSendMediaMessages bool `json:"can_send_media_messages,omitempty"` + CanSendPolls bool `json:"can_send_polls,omitempty"` + CanSendOtherMessages bool `json:"can_send_other_messages,omitempty"` + CanAddWebPagePreviews bool `json:"can_add_web_page_previews,omitempty"` +} + +// ChatPermissions describes actions that a non-administrator user is allowed to take in a chat. +type ChatPermissions struct { + CanSendMessages bool `json:"can_send_messages,omitempty"` + CanSendMediaMessages bool `json:"can_send_media_messages,omitempty"` + CanSendPolls bool `json:"can_send_polls,omitempty"` + CanSendOtherMessages bool `json:"can_send_other_messages,omitempty"` + CanAddWebPagePreviews bool `json:"can_add_web_page_previews,omitempty"` + CanChangeInfo bool `json:"can_change_info,omitempty"` + CanInviteUsers bool `json:"can_invite_users,omitempty"` + CanPinMessages bool `json:"can_pin_messages,omitempty"` +} + +// ResponseParameters contains information about why a request was unsuccessful. +type ResponseParameters struct { + MigrateToChatID ChatID `json:"migrate_to_chat_id,omitempty"` + RetryAfter int64 `json:"retry_after,omitempty"` +} + +// Update object represents an incoming update. // Only one of the optional parameters can be present in any given update. type Update struct { UpdateID uint64 `json:"update_id"` // Optional - Message *Message `json:"message"` - EditedMessage *Message `json:"edited_message"` - ChannelPost *Message `json:"channel_post"` - EditedChannelPost *Message `json:"edited_channel_post"` - InlineQuery *InlineQuery `json:"inline_query"` - ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"` - CallbackQuery *CallbackQuery `json:"callback_query"` -} - + Message *Message `json:"message,omitempty"` + EditedMessage *Message `json:"edited_message,omitempty"` + ChannelPost *Message `json:"channel_post,omitempty"` + EditedChannelPost *Message `json:"edited_channel_post,omitempty"` + InlineQuery *InlineQuery `json:"inline_query,omitempty"` + ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"` + CallbackQuery *CallbackQuery `json:"callback_query,omitempty"` + ShippingQuery *ShippingQuery `json:"shipping_query,omitempty"` + PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query,omitempty"` + Poll *Poll `json:"poll,omitempty"` +} + +// WebhookInfo contains information about the current status of a webhook. type WebhookInfo struct { URL string `json:"url"` HasCustomCertificate bool `json:"has_custom_certificate"` PendingUpdateCount int `json:"pending_update_count"` - LastErrorDate uint64 `json:"last_error_date"` - LastErrorMessage string `json:"last_error_message"` - MaxConnections int `json:"max_connections"` - AllowedUpdates []string `json:"allowed_updates"` -} - -type Invoice struct { - Title string - Description string - StartParameter string - Currency string - TotalAmount int -} - -type ShippingAddress struct { + LastErrorDate uint64 `json:"last_error_date,omitempty"` + LastErrorMessage string `json:"last_error_message,omitempty"` + MaxConnections int `json:"max_connections,omitempty"` + AllowedUpdates []string `json:"allowed_updates,omitempty"` } diff --git a/types_games.go b/types_games.go new file mode 100644 index 0000000..41f3d75 --- /dev/null +++ b/types_games.go @@ -0,0 +1,21 @@ +package micha + +// Game object represents a game. +// Use BotFather to create and edit games, their short names will act as unique identifiers. +type Game struct { + Title string `json:"title"` + Description string `json:"description"` + Photo []PhotoSize `json:"photo"` + + // Optional + Text string `json:"text"` + TextEntities []MessageEntity `json:"text_entities"` + Animation *Animation `json:"animation"` +} + +// GameHighScore object represents one row of the high scores table for a game. +type GameHighScore struct { + Position int `json:"position"` + User User `json:"user"` + Score int `json:"score"` +} diff --git a/types_inline.go b/types_inline.go index c2b568c..e890202 100644 --- a/types_inline.go +++ b/types_inline.go @@ -16,6 +16,16 @@ const ( INLINE_TYPE_RESULT_GAME InlineResultType = "game" ) +// InlineQuery object represents an incoming inline query. +// When the user sends an empty query, your bot could return some default or trending results. +type InlineQuery struct { + ID string `json:"id"` + From User `json:"from"` + Location *Location `json:"location,omitempty"` + Query string `json:"query"` + Offset string `json:"offset"` +} + type InlineResultType string type InlineQueryResults []InlineQueryResult diff --git a/types_payments.go b/types_payments.go new file mode 100644 index 0000000..5c37419 --- /dev/null +++ b/types_payments.go @@ -0,0 +1,29 @@ +package micha + +type Invoice struct { + Title string + Description string + StartParameter string + Currency string + TotalAmount int +} + +type SuccessfulPayment struct { + // TODO +} + +type ShippingAddress struct { + // TODO +} + +type PassportData struct { + // TODO +} + +type ShippingQuery struct { + // TODO +} + +type PreCheckoutQuery struct { + // TODO +} diff --git a/types_stickers.go b/types_stickers.go new file mode 100644 index 0000000..6b70991 --- /dev/null +++ b/types_stickers.go @@ -0,0 +1,33 @@ +package micha + +// Sticker object represents a WebP image, so-called sticker. +type Sticker struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + IsAnimated bool `json:"is_animated,omitempty"` + + // Optional + Thumb *PhotoSize `json:"thumb,omitempty"` + Emoji string `json:"emoji,omitempty"` + SetName string `json:"set_name,omitempty"` + MaskPosition *MaskPosition `json:"mask_position,omitempty"` + FileSize uint64 `json:"file_size,omitempty"` +} + +// StickerSet object represents a sticker set. +type StickerSet struct { + Name string `json:"name"` + Title string `json:"title"` + IsAnimated bool `json:"is_animated"` + ContainsMasks bool `json:"contains_masks"` + Stickers []Sticker `json:"stickers"` +} + +// MaskPosition object describes the position on faces where a mask should be placed by default. +type MaskPosition struct { + Point string `json:"point"` + XShift float64 `json:"x_shift"` + YShift float64 `json:"y_shift"` + Scale float64 `json:"scale"` +}