package tgbotapi import ( "io" "net/url" "strconv" ) // Telegram constants const ( // APIEndpoint is the endpoint for all API methods, // with formatting for Sprintf. APIEndpoint = "https://api.telegram.org/bot%s/%s" // FileEndpoint is the endpoint for downloading a file from Telegram. FileEndpoint = "https://api.telegram.org/file/bot%s/%s" ) // Constant values for ChatActions const ( ChatTyping = "typing" ChatUploadPhoto = "upload_photo" ChatRecordVideo = "record_video" ChatUploadVideo = "upload_video" ChatRecordAudio = "record_audio" ChatUploadAudio = "upload_audio" ChatUploadDocument = "upload_document" ChatFindLocation = "find_location" ChatRecordVideoNote = "record_video_note" ChatUploadVideoNote = "upload_video_note" ) // API errors const ( // ErrAPIForbidden happens when a token is bad ErrAPIForbidden = "forbidden" ) // Constant values for ParseMode in MessageConfig const ( ModeMarkdown = "Markdown" ModeMarkdownV2 = "MarkdownV2" ModeHTML = "HTML" ) // Library errors const ( // ErrBadFileType happens when you pass an unknown type ErrBadFileType = "bad file type" ErrBadURL = "bad or empty url" ) // Chattable is any config type that can be sent. type Chattable interface { params() (Params, error) method() string } // Fileable is any config type that can be sent that includes a file. type Fileable interface { Chattable name() string getFile() interface{} useExistingFile() bool } // BaseChat is base type for all chat config types. type BaseChat struct { ChatID int64 // required ChannelUsername string ReplyToMessageID int ReplyMarkup interface{} DisableNotification bool } func (chat *BaseChat) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername) params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID) params.AddBool("disable_notification", chat.DisableNotification) err := params.AddInterface("reply_markup", chat.ReplyMarkup) return params, err } // BaseFile is a base type for all file config types. type BaseFile struct { BaseChat File interface{} FileID string UseExisting bool MimeType string FileSize int } func (file BaseFile) params() (Params, error) { params, err := file.BaseChat.params() params.AddNonEmpty("mime_type", file.MimeType) params.AddNonZero("file_size", file.FileSize) return params, err } func (file BaseFile) getFile() interface{} { return file.File } func (file BaseFile) useExistingFile() bool { return file.UseExisting } // BaseEdit is base type of all chat edits. type BaseEdit struct { ChatID int64 ChannelUsername string MessageID int InlineMessageID string ReplyMarkup *InlineKeyboardMarkup } func (edit BaseEdit) params() (Params, error) { params := make(Params) if edit.InlineMessageID != "" { params["inline_message_id"] = edit.InlineMessageID } else { params.AddFirstValid("chat_id", edit.ChatID, edit.ChannelUsername) params.AddNonZero("message_id", edit.MessageID) } err := params.AddInterface("reply_markup", edit.ReplyMarkup) return params, err } // MessageConfig contains information about a SendMessage request. type MessageConfig struct { BaseChat Text string ParseMode string DisableWebPagePreview bool } func (config MessageConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params.AddNonEmpty("text", config.Text) params.AddBool("disable_web_page_preview", config.DisableWebPagePreview) params.AddNonEmpty("parse_mode", config.ParseMode) return params, nil } func (config MessageConfig) method() string { return "sendMessage" } // ForwardConfig contains information about a ForwardMessage request. type ForwardConfig struct { BaseChat FromChatID int64 // required FromChannelUsername string MessageID int // required } func (config ForwardConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params.AddNonZero64("from_chat_id", config.FromChatID) params.AddNonZero("message_id", config.MessageID) return params, nil } func (config ForwardConfig) method() string { return "forwardMessage" } // PhotoConfig contains information about a SendPhoto request. type PhotoConfig struct { BaseFile Caption string ParseMode string } func (config PhotoConfig) params() (Params, error) { params, err := config.BaseFile.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) return params, err } func (config PhotoConfig) name() string { return "photo" } func (config PhotoConfig) method() string { return "sendPhoto" } // AudioConfig contains information about a SendAudio request. type AudioConfig struct { BaseFile Caption string ParseMode string Duration int Performer string Title string } func (config AudioConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params.AddNonEmpty(config.name(), config.FileID) params.AddNonZero("duration", config.Duration) params.AddNonEmpty("performer", config.Performer) params.AddNonEmpty("title", config.Title) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) return params, nil } func (config AudioConfig) name() string { return "audio" } func (config AudioConfig) method() string { return "sendAudio" } // DocumentConfig contains information about a SendDocument request. type DocumentConfig struct { BaseFile Caption string ParseMode string } func (config DocumentConfig) params() (Params, error) { params, err := config.BaseFile.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) return params, err } func (config DocumentConfig) name() string { return "document" } func (config DocumentConfig) method() string { return "sendDocument" } // StickerConfig contains information about a SendSticker request. type StickerConfig struct { BaseFile } func (config StickerConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonEmpty(config.name(), config.FileID) return params, err } func (config StickerConfig) name() string { return "sticker" } func (config StickerConfig) method() string { return "sendSticker" } // VideoConfig contains information about a SendVideo request. type VideoConfig struct { BaseFile Duration int Caption string ParseMode string SupportsStreaming bool } func (config VideoConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonZero("duration", config.Duration) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) params.AddBool("supports_streaming", config.SupportsStreaming) return params, err } func (config VideoConfig) name() string { return "video" } func (config VideoConfig) method() string { return "sendVideo" } // AnimationConfig contains information about a SendAnimation request. type AnimationConfig struct { BaseFile Duration int Caption string ParseMode string } func (config AnimationConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonZero("duration", config.Duration) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) return params, err } func (config AnimationConfig) name() string { return "animation" } func (config AnimationConfig) method() string { return "sendAnimation" } // VideoNoteConfig contains information about a SendVideoNote request. type VideoNoteConfig struct { BaseFile Duration int Length int } func (config VideoNoteConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonZero("duration", config.Duration) params.AddNonZero("length", config.Length) return params, err } func (config VideoNoteConfig) name() string { return "video_note" } func (config VideoNoteConfig) method() string { return "sendVideoNote" } // VoiceConfig contains information about a SendVoice request. type VoiceConfig struct { BaseFile Caption string ParseMode string Duration int } func (config VoiceConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonEmpty(config.name(), config.FileID) params.AddNonZero("duration", config.Duration) params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("parse_mode", config.ParseMode) return params, err } func (config VoiceConfig) name() string { return "voice" } func (config VoiceConfig) method() string { return "sendVoice" } // LocationConfig contains information about a SendLocation request. type LocationConfig struct { BaseChat Latitude float64 // required Longitude float64 // required LivePeriod int // optional } func (config LocationConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonZeroFloat("latitude", config.Latitude) params.AddNonZeroFloat("longitude", config.Longitude) params.AddNonZero("live_period", config.LivePeriod) return params, err } func (config LocationConfig) method() string { return "sendLocation" } // EditMessageLiveLocationConfig allows you to update a live location. type EditMessageLiveLocationConfig struct { BaseEdit Latitude float64 // required Longitude float64 // required } func (config EditMessageLiveLocationConfig) params() (Params, error) { params, err := config.BaseEdit.params() params.AddNonZeroFloat("latitude", config.Latitude) params.AddNonZeroFloat("longitude", config.Longitude) return params, err } func (config EditMessageLiveLocationConfig) method() string { return "editMessageLiveLocation" } // StopMessageLiveLocationConfig stops updating a live location. type StopMessageLiveLocationConfig struct { BaseEdit } func (config StopMessageLiveLocationConfig) params() (Params, error) { return config.BaseEdit.params() } func (config StopMessageLiveLocationConfig) method() string { return "stopMessageLiveLocation" } // VenueConfig contains information about a SendVenue request. type VenueConfig struct { BaseChat Latitude float64 // required Longitude float64 // required Title string // required Address string // required FoursquareID string } func (config VenueConfig) params() (Params, error) { params, err := config.BaseChat.params() params.AddNonZeroFloat("latitude", config.Latitude) params.AddNonZeroFloat("longitude", config.Longitude) params["title"] = config.Title params["address"] = config.Address params.AddNonEmpty("foursquare_id", config.FoursquareID) return params, err } func (config VenueConfig) method() string { return "sendVenue" } // ContactConfig allows you to send a contact. type ContactConfig struct { BaseChat PhoneNumber string FirstName string LastName string VCard string } func (config ContactConfig) params() (Params, error) { params, err := config.BaseChat.params() params["phone_number"] = config.PhoneNumber params["first_name"] = config.FirstName params.AddNonEmpty("last_name", config.LastName) params.AddNonEmpty("vcard", config.VCard) return params, err } func (config ContactConfig) method() string { return "sendContact" } // SendPollConfig allows you to send a poll. type SendPollConfig struct { BaseChat Question string Options []string IsAnonymous bool Type string AllowsMultipleAnswers bool CorrectOptionID int64 Explanation string ExplanationParseMode string OpenPeriod int CloseDate int IsClosed bool } func (config SendPollConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params["question"] = config.Question err = params.AddInterface("options", config.Options) params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous) params.AddNonEmpty("type", config.Type) params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers) params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10) params.AddBool("is_closed", config.IsClosed) params.AddNonEmpty("explanation", config.Explanation) params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode) params.AddNonZero("open_period", config.OpenPeriod) params.AddNonZero("close_date", config.CloseDate) return params, err } func (SendPollConfig) method() string { return "sendPoll" } // GameConfig allows you to send a game. type GameConfig struct { BaseChat GameShortName string } func (config GameConfig) params() (Params, error) { params, err := config.BaseChat.params() params["game_short_name"] = config.GameShortName return params, err } func (config GameConfig) method() string { return "sendGame" } // SetGameScoreConfig allows you to update the game score in a chat. type SetGameScoreConfig struct { UserID int Score int Force bool DisableEditMessage bool ChatID int64 ChannelUsername string MessageID int InlineMessageID string } func (config SetGameScoreConfig) params() (Params, error) { params := make(Params) params.AddNonZero("user_id", config.UserID) params.AddNonZero("scrore", config.Score) params.AddBool("disable_edit_message", config.DisableEditMessage) if config.InlineMessageID != "" { params["inline_message_id"] = config.InlineMessageID } else { params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params.AddNonZero("message_id", config.MessageID) } return params, nil } func (config SetGameScoreConfig) method() string { return "setGameScore" } // GetGameHighScoresConfig allows you to fetch the high scores for a game. type GetGameHighScoresConfig struct { UserID int ChatID int ChannelUsername string MessageID int InlineMessageID string } func (config GetGameHighScoresConfig) params() (Params, error) { params := make(Params) params.AddNonZero("user_id", config.UserID) if config.InlineMessageID != "" { params["inline_message_id"] = config.InlineMessageID } else { params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params.AddNonZero("message_id", config.MessageID) } return params, nil } func (config GetGameHighScoresConfig) method() string { return "getGameHighScores" } // ChatActionConfig contains information about a SendChatAction request. type ChatActionConfig struct { BaseChat Action string // required } func (config ChatActionConfig) params() (Params, error) { params, err := config.BaseChat.params() params["action"] = config.Action return params, err } func (config ChatActionConfig) method() string { return "sendChatAction" } // EditMessageTextConfig allows you to modify the text in a message. type EditMessageTextConfig struct { BaseEdit Text string ParseMode string DisableWebPagePreview bool } func (config EditMessageTextConfig) params() (Params, error) { params, err := config.BaseEdit.params() params["text"] = config.Text params.AddNonEmpty("parse_mode", config.ParseMode) params.AddBool("disable_web_page_preview", config.DisableWebPagePreview) return params, err } func (config EditMessageTextConfig) method() string { return "editMessageText" } // EditMessageCaptionConfig allows you to modify the caption of a message. type EditMessageCaptionConfig struct { BaseEdit Caption string ParseMode string } func (config EditMessageCaptionConfig) params() (Params, error) { params, err := config.BaseEdit.params() params["caption"] = config.Caption params.AddNonEmpty("parse_mode", config.ParseMode) return params, err } func (config EditMessageCaptionConfig) method() string { return "editMessageCaption" } // EditMessageMediaConfig contains information about editing a message's media. type EditMessageMediaConfig struct { BaseEdit Media interface{} } func (EditMessageMediaConfig) method() string { return "editMessageMedia" } func (config EditMessageMediaConfig) params() (Params, error) { params, err := config.BaseEdit.params() params.AddInterface("media", config.Media) return params, err } // EditMessageReplyMarkupConfig allows you to modify the reply markup // of a message. type EditMessageReplyMarkupConfig struct { BaseEdit } func (config EditMessageReplyMarkupConfig) params() (Params, error) { return config.BaseEdit.params() } func (config EditMessageReplyMarkupConfig) method() string { return "editMessageReplyMarkup" } // StopPollConfig allows you to stop a poll sent by the bot. type StopPollConfig struct { BaseEdit } func (config StopPollConfig) params() (Params, error) { return config.BaseEdit.params() } func (StopPollConfig) method() string { return "stopPoll" } // UserProfilePhotosConfig contains information about a // GetUserProfilePhotos request. type UserProfilePhotosConfig struct { UserID int Offset int Limit int } func (UserProfilePhotosConfig) method() string { return "getUserProfilePhotos" } func (config UserProfilePhotosConfig) params() (Params, error) { params := make(Params) params.AddNonZero("user_id", config.UserID) params.AddNonZero("offset", config.Offset) params.AddNonZero("limit", config.Limit) return params, nil } // FileConfig has information about a file hosted on Telegram. type FileConfig struct { FileID string } func (FileConfig) method() string { return "getFile" } func (config FileConfig) params() (Params, error) { params := make(Params) params["file_id"] = config.FileID return params, nil } // UpdateConfig contains information about a GetUpdates request. type UpdateConfig struct { Offset int Limit int Timeout int } func (UpdateConfig) method() string { return "getUpdates" } func (config UpdateConfig) params() (Params, error) { params := make(Params) params.AddNonZero("offset", config.Offset) params.AddNonZero("limit", config.Limit) params.AddNonZero("timeout", config.Timeout) return params, nil } // WebhookConfig contains information about a SetWebhook request. type WebhookConfig struct { URL *url.URL Certificate interface{} MaxConnections int AllowedUpdates []string } func (config WebhookConfig) method() string { return "setWebhook" } func (config WebhookConfig) params() (Params, error) { params := make(Params) if config.URL != nil { params["url"] = config.URL.String() } params.AddNonZero("max_connections", config.MaxConnections) params.AddInterface("allowed_updates", config.AllowedUpdates) return params, nil } func (config WebhookConfig) name() string { return "certificate" } func (config WebhookConfig) getFile() interface{} { return config.Certificate } func (config WebhookConfig) useExistingFile() bool { return config.URL != nil } // RemoveWebhookConfig is a helper to remove a webhook. type RemoveWebhookConfig struct { } func (config RemoveWebhookConfig) method() string { return "setWebhook" } func (config RemoveWebhookConfig) params() (Params, error) { return nil, nil } // FileBytes contains information about a set of bytes to upload // as a File. type FileBytes struct { Name string Bytes []byte } // FileReader contains information about a reader to upload as a File. // If Size is -1, it will read the entire Reader into memory to // calculate a Size. type FileReader struct { Name string Reader io.Reader Size int64 } // InlineConfig contains information on making an InlineQuery response. type InlineConfig struct { InlineQueryID string `json:"inline_query_id"` Results []interface{} `json:"results"` CacheTime int `json:"cache_time"` IsPersonal bool `json:"is_personal"` NextOffset string `json:"next_offset"` SwitchPMText string `json:"switch_pm_text"` SwitchPMParameter string `json:"switch_pm_parameter"` } func (config InlineConfig) method() string { return "answerInlineQuery" } func (config InlineConfig) params() (Params, error) { params := make(Params) params["inline_query_id"] = config.InlineQueryID params.AddNonZero("cache_time", config.CacheTime) params.AddBool("is_personal", config.IsPersonal) params.AddNonEmpty("next_offset", config.NextOffset) params.AddNonEmpty("switch_pm_text", config.SwitchPMText) params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter) if err := params.AddInterface("results", config.Results); err != nil { return params, err } return params, nil } // CallbackConfig contains information on making a CallbackQuery response. type CallbackConfig struct { CallbackQueryID string `json:"callback_query_id"` Text string `json:"text"` ShowAlert bool `json:"show_alert"` URL string `json:"url"` CacheTime int `json:"cache_time"` } func (config CallbackConfig) method() string { return "answerCallbackQuery" } func (config CallbackConfig) params() (Params, error) { params := make(Params) params["callback_query_id"] = config.CallbackQueryID params.AddNonEmpty("text", config.Text) params.AddBool("show_alert", config.ShowAlert) params.AddNonEmpty("url", config.URL) params.AddNonZero("cache_time", config.CacheTime) return params, nil } // ChatMemberConfig contains information about a user in a chat for use // with administrative functions such as kicking or unbanning a user. type ChatMemberConfig struct { ChatID int64 SuperGroupUsername string ChannelUsername string UserID int } // UnbanChatMemberConfig allows you to unban a user. type UnbanChatMemberConfig struct { ChatMemberConfig } func (config UnbanChatMemberConfig) method() string { return "unbanChatMember" } func (config UnbanChatMemberConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddNonZero("user_id", config.UserID) return params, nil } // KickChatMemberConfig contains extra fields to kick user type KickChatMemberConfig struct { ChatMemberConfig UntilDate int64 } func (config KickChatMemberConfig) method() string { return "kickChatMember" } func (config KickChatMemberConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) params.AddNonZero("user_id", config.UserID) params.AddNonZero64("until_date", config.UntilDate) return params, nil } // RestrictChatMemberConfig contains fields to restrict members of chat type RestrictChatMemberConfig struct { ChatMemberConfig UntilDate int64 Permissions *ChatPermissions } func (config RestrictChatMemberConfig) method() string { return "restrictChatMember" } func (config RestrictChatMemberConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddNonZero("user_id", config.UserID) if err := params.AddInterface("permissions", config.Permissions); err != nil { return params, err } params.AddNonZero64("until_date", config.UntilDate) return params, nil } // PromoteChatMemberConfig contains fields to promote members of chat type PromoteChatMemberConfig struct { ChatMemberConfig CanChangeInfo bool CanPostMessages bool CanEditMessages bool CanDeleteMessages bool CanInviteUsers bool CanRestrictMembers bool CanPinMessages bool CanPromoteMembers bool } func (config PromoteChatMemberConfig) method() string { return "promoteChatMember" } func (config PromoteChatMemberConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddNonZero("user_id", config.UserID) params.AddBool("can_change_info", config.CanChangeInfo) params.AddBool("can_post_messages", config.CanPostMessages) params.AddBool("can_edit_messages", config.CanEditMessages) params.AddBool("can_delete_messages", config.CanDeleteMessages) params.AddBool("can_invite_users", config.CanInviteUsers) params.AddBool("can_restrict_members", config.CanRestrictMembers) params.AddBool("can_pin_messages", config.CanPinMessages) params.AddBool("can_promote_members", config.CanPromoteMembers) return params, nil } // SetChatAdministratorCustomTitle sets the title of an administrative user // promoted by the bot for a chat. type SetChatAdministratorCustomTitle struct { ChatMemberConfig CustomTitle string } func (SetChatAdministratorCustomTitle) method() string { return "setChatAdministratorCustomTitle" } func (config SetChatAdministratorCustomTitle) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddNonZero("user_id", config.UserID) params.AddNonEmpty("custom_title", config.CustomTitle) return params, nil } // ChatConfig contains information about getting information on a chat. type ChatConfig struct { ChatID int64 SuperGroupUsername string } func (config ChatConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) return params, nil } // ChatInfoConfig contains information about getting chat information. type ChatInfoConfig struct { ChatConfig } func (ChatInfoConfig) method() string { return "getChat" } // ChatMemberCountConfig contains information about getting the number of users in a chat. type ChatMemberCountConfig struct { ChatConfig } func (ChatMemberCountConfig) method() string { return "getChatMembersCount" } // ChatAdministratorsConfig contains information about getting chat administrators. type ChatAdministratorsConfig struct { ChatConfig } func (ChatAdministratorsConfig) method() string { return "getChatAdministrators" } // SetChatPermissionsConfig allows you to set default permissions for the // members in a group. The bot must be an administrator and have rights to // restrict members. type SetChatPermissionsConfig struct { ChatConfig Permissions *ChatPermissions } func (SetChatPermissionsConfig) method() string { return "setChatPermissions" } func (config SetChatPermissionsConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) params.AddInterface("permissions", config.Permissions) return params, nil } // ChatInviteLinkConfig contains information about getting a chat link. // // Note that generating a new link will revoke any previous links. type ChatInviteLinkConfig struct { ChatConfig } func (ChatInviteLinkConfig) method() string { return "exportChatInviteLink" } func (config ChatInviteLinkConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) return params, nil } // LeaveChatConfig allows you to leave a chat. type LeaveChatConfig struct { ChatID int64 ChannelUsername string } func (config LeaveChatConfig) method() string { return "leaveChat" } func (config LeaveChatConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) return params, nil } // ChatConfigWithUser contains information about a chat and a user. type ChatConfigWithUser struct { ChatID int64 SuperGroupUsername string UserID int } func (config ChatConfigWithUser) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) params.AddNonZero("user_id", config.UserID) return params, nil } // GetChatMemberConfig is information about getting a specific member in a chat. type GetChatMemberConfig struct { ChatConfigWithUser } func (GetChatMemberConfig) method() string { return "getChatMember" } // InvoiceConfig contains information for sendInvoice request. type InvoiceConfig struct { BaseChat Title string // required Description string // required Payload string // required ProviderToken string // required StartParameter string // required Currency string // required Prices []LabeledPrice // required ProviderData string PhotoURL string PhotoSize int PhotoWidth int PhotoHeight int NeedName bool NeedPhoneNumber bool NeedEmail bool NeedShippingAddress bool SendPhoneNumberToProvider bool SendEmailToProvider bool IsFlexible bool } func (config InvoiceConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params["title"] = config.Title params["description"] = config.Description params["payload"] = config.Payload params["provider_token"] = config.ProviderToken params["start_parameter"] = config.StartParameter params["currency"] = config.Currency if err = params.AddInterface("prices", config.Prices); err != nil { return params, err } params.AddNonEmpty("provider_data", config.ProviderData) params.AddNonEmpty("photo_url", config.PhotoURL) params.AddNonZero("photo_size", config.PhotoSize) params.AddNonZero("photo_width", config.PhotoWidth) params.AddNonZero("photo_height", config.PhotoHeight) params.AddBool("need_name", config.NeedName) params.AddBool("need_phone_number", config.NeedPhoneNumber) params.AddBool("need_email", config.NeedEmail) params.AddBool("need_shipping_address", config.NeedShippingAddress) params.AddBool("is_flexible", config.IsFlexible) params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider) params.AddBool("send_email_to_provider", config.SendEmailToProvider) return params, nil } func (config InvoiceConfig) method() string { return "sendInvoice" } // ShippingConfig contains information for answerShippingQuery request. type ShippingConfig struct { ShippingQueryID string // required OK bool // required ShippingOptions []ShippingOption ErrorMessage string } // PreCheckoutConfig conatins information for answerPreCheckoutQuery request. type PreCheckoutConfig struct { PreCheckoutQueryID string // required OK bool // required ErrorMessage string } // DeleteMessageConfig contains information of a message in a chat to delete. type DeleteMessageConfig struct { ChannelUsername string ChatID int64 MessageID int } func (config DeleteMessageConfig) method() string { return "deleteMessage" } func (config DeleteMessageConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params.AddNonZero("message_id", config.MessageID) return params, nil } // PinChatMessageConfig contains information of a message in a chat to pin. type PinChatMessageConfig struct { ChatID int64 ChannelUsername string MessageID int DisableNotification bool } func (config PinChatMessageConfig) method() string { return "pinChatMessage" } func (config PinChatMessageConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params.AddNonZero("message_id", config.MessageID) params.AddBool("disable_notification", config.DisableNotification) return params, nil } // UnpinChatMessageConfig contains information of chat to unpin. type UnpinChatMessageConfig struct { ChatID int64 ChannelUsername string } func (config UnpinChatMessageConfig) method() string { return "unpinChatMessage" } func (config UnpinChatMessageConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) return params, nil } // SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo. type SetChatPhotoConfig struct { BaseFile } func (config SetChatPhotoConfig) method() string { return "setChatPhoto" } func (config SetChatPhotoConfig) name() string { return "photo" } func (config SetChatPhotoConfig) getFile() interface{} { return config.File } func (config SetChatPhotoConfig) useExistingFile() bool { return config.UseExisting } // DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo. type DeleteChatPhotoConfig struct { ChatID int64 ChannelUsername string } func (config DeleteChatPhotoConfig) method() string { return "deleteChatPhoto" } func (config DeleteChatPhotoConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) return params, nil } // SetChatTitleConfig allows you to set the title of something other than a private chat. type SetChatTitleConfig struct { ChatID int64 ChannelUsername string Title string } func (config SetChatTitleConfig) method() string { return "setChatTitle" } func (config SetChatTitleConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params["title"] = config.Title return params, nil } // SetChatDescriptionConfig allows you to set the description of a supergroup or channel. type SetChatDescriptionConfig struct { ChatID int64 ChannelUsername string Description string } func (config SetChatDescriptionConfig) method() string { return "setChatDescription" } func (config SetChatDescriptionConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params["description"] = config.Description return params, nil } // GetStickerSetConfig allows you to get the stickers in a set. type GetStickerSetConfig struct { Name string } func (config GetStickerSetConfig) method() string { return "getStickerSet" } func (config GetStickerSetConfig) params() (Params, error) { params := make(Params) params["name"] = config.Name return params, nil } // UploadStickerConfig allows you to upload a sticker for use in a set later. type UploadStickerConfig struct { UserID int64 PNGSticker interface{} } func (config UploadStickerConfig) method() string { return "uploadStickerFile" } func (config UploadStickerConfig) params() (Params, error) { params := make(Params) params.AddNonZero64("user_id", config.UserID) return params, nil } func (config UploadStickerConfig) name() string { return "png_sticker" } func (config UploadStickerConfig) getFile() interface{} { return config.PNGSticker } func (config UploadStickerConfig) useExistingFile() bool { _, ok := config.PNGSticker.(string) return ok } // NewStickerSetConfig allows creating a new sticker set. // // You must set either PNGSticker or TGSSticker. type NewStickerSetConfig struct { UserID int64 Name string Title string PNGSticker interface{} TGSSticker interface{} Emojis string ContainsMasks bool MaskPosition *MaskPosition } func (config NewStickerSetConfig) method() string { return "createNewStickerSet" } func (config NewStickerSetConfig) params() (Params, error) { params := make(Params) params.AddNonZero64("user_id", config.UserID) params["name"] = config.Name params["title"] = config.Title if sticker, ok := config.PNGSticker.(string); ok { params[config.name()] = sticker } else if sticker, ok := config.TGSSticker.(string); ok { params[config.name()] = sticker } params["emojis"] = config.Emojis params.AddBool("contains_masks", config.ContainsMasks) err := params.AddInterface("mask_position", config.MaskPosition) return params, err } func (config NewStickerSetConfig) getFile() interface{} { return config.PNGSticker } func (config NewStickerSetConfig) name() string { return "png_sticker" } func (config NewStickerSetConfig) useExistingFile() bool { if config.PNGSticker != nil { _, ok := config.PNGSticker.(string) return ok } if config.TGSSticker != nil { _, ok := config.TGSSticker.(string) return ok } panic("NewStickerSetConfig had nil PNGSticker and TGSSticker") } // AddStickerConfig allows you to add a sticker to a set. type AddStickerConfig struct { UserID int64 Name string PNGSticker interface{} TGSSticker interface{} Emojis string MaskPosition *MaskPosition } func (config AddStickerConfig) method() string { return "addStickerToSet" } func (config AddStickerConfig) params() (Params, error) { params := make(Params) params.AddNonZero64("user_id", config.UserID) params["name"] = config.Name params["emojis"] = config.Emojis if sticker, ok := config.PNGSticker.(string); ok { params[config.name()] = sticker } else if sticker, ok := config.TGSSticker.(string); ok { params[config.name()] = sticker } err := params.AddInterface("mask_position", config.MaskPosition) return params, err } func (config AddStickerConfig) name() string { return "png_sticker" } func (config AddStickerConfig) getFile() interface{} { return config.PNGSticker } func (config AddStickerConfig) useExistingFile() bool { _, ok := config.PNGSticker.(string) return ok } // SetStickerPositionConfig allows you to change the position of a sticker in a set. type SetStickerPositionConfig struct { Sticker string Position int } func (config SetStickerPositionConfig) method() string { return "setStickerPositionInSet" } func (config SetStickerPositionConfig) params() (Params, error) { params := make(Params) params["sticker"] = config.Sticker params.AddNonZero("position", config.Position) return params, nil } // DeleteStickerConfig allows you to delete a sticker from a set. type DeleteStickerConfig struct { Sticker string } func (config DeleteStickerConfig) method() string { return "deleteStickerFromSet" } func (config DeleteStickerConfig) params() (Params, error) { params := make(Params) params["sticker"] = config.Sticker return params, nil } // SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set. type SetStickerSetThumbConfig struct { Name string UserID int Thumb interface{} } func (config SetStickerSetThumbConfig) method() string { return "setStickerSetThumb" } func (config SetStickerSetThumbConfig) params() (Params, error) { params := make(Params) params["name"] = config.Name params.AddNonZero("user_id", config.UserID) if thumb, ok := config.Thumb.(string); ok { params["thumb"] = thumb } return params, nil } func (config SetStickerSetThumbConfig) name() string { return "thumb" } func (config SetStickerSetThumbConfig) getFile() interface{} { return config.Thumb } func (config SetStickerSetThumbConfig) useExistingFile() bool { _, ok := config.Thumb.(string) return ok } // SetChatStickerSetConfig allows you to set the sticker set for a supergroup. type SetChatStickerSetConfig struct { ChatID int64 SuperGroupUsername string StickerSetName string } func (config SetChatStickerSetConfig) method() string { return "setChatStickerSet" } func (config SetChatStickerSetConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) params["sticker_set_name"] = config.StickerSetName return params, nil } // DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set. type DeleteChatStickerSetConfig struct { ChatID int64 SuperGroupUsername string } func (config DeleteChatStickerSetConfig) method() string { return "deleteChatStickerSet" } func (config DeleteChatStickerSetConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) return params, nil } // MediaGroupConfig allows you to send a group of media. // // Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo). type MediaGroupConfig struct { ChatID int64 ChannelUsername string Media []interface{} DisableNotification bool ReplyToMessageID int } func (config MediaGroupConfig) method() string { return "sendMediaGroup" } func (config MediaGroupConfig) params() (Params, error) { params := make(Params) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) if err := params.AddInterface("media", config.Media); err != nil { return params, nil } params.AddBool("disable_notification", config.DisableNotification) params.AddNonZero("reply_to_message_id", config.ReplyToMessageID) return params, nil } // DiceConfig allows you to send a random dice roll to Telegram. type DiceConfig struct { BaseChat Emoji string } func (config DiceConfig) method() string { return "sendDice" } func (config DiceConfig) params() (Params, error) { params, err := config.BaseChat.params() if err != nil { return params, err } params.AddNonEmpty("emoji", config.Emoji) return params, err } // GetMyCommandsConfig gets a list of the currently registered commands. type GetMyCommandsConfig struct{} func (config GetMyCommandsConfig) method() string { return "getMyCommands" } func (config GetMyCommandsConfig) params() (Params, error) { return make(Params), nil } // SetMyCommandsConfig sets a list of commands the bot understands. type SetMyCommandsConfig struct { commands []BotCommand } func (config SetMyCommandsConfig) method() string { return "setMyCommands" } func (config SetMyCommandsConfig) params() (Params, error) { params := make(Params) err := params.AddInterface("commands", config.commands) return params, err }