300 lines
11 KiB
Go
300 lines
11 KiB
Go
package telegram
|
||
|
||
import (
|
||
"time"
|
||
|
||
http "github.com/valyala/fasthttp"
|
||
)
|
||
|
||
type (
|
||
// Update represents an incoming update.
|
||
//
|
||
// At most one of the optional parameters can be present in any given update.
|
||
Update struct {
|
||
// The update‘s unique identifier. Update identifiers start from a
|
||
// certain positive number and increase sequentially. This ID becomes
|
||
// especially handy if you’re using Webhooks, since it allows you to
|
||
// ignore repeated updates or to restore the correct update sequence,
|
||
// should they get out of order.
|
||
UpdateID int `json:"update_id"`
|
||
|
||
// New incoming message of any kind — text, photo, sticker, etc.
|
||
Message *Message `json:"message,omitempty"`
|
||
|
||
// New version of a message that is known to the bot and was edited
|
||
EditedMessage *Message `json:"edited_message,omitempty"`
|
||
|
||
// New incoming channel post of any kind — text, photo, sticker, etc.
|
||
ChannelPost *Message `json:"channel_post,omitempty"`
|
||
|
||
// New version of a channel post that is known to the bot and was edited
|
||
EditedChannelPost *Message `json:"adited_channel_post,omitempty"`
|
||
|
||
// New incoming inline query
|
||
InlineQuery *InlineQuery `json:"inline_query,omitempty"`
|
||
|
||
// The result of an inline query that was chosen by a user and sent to
|
||
// their chat partner.
|
||
ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"`
|
||
|
||
// New incoming callback query
|
||
CallbackQuery *CallbackQuery `json:"callback_query,omitempty"`
|
||
|
||
// New incoming shipping query. Only for invoices with flexible price
|
||
ShippingQuery *ShippingQuery `json:"shipping_query,omitempty"`
|
||
|
||
// New incoming pre-checkout query. Contains full information about
|
||
// checkout
|
||
PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query,omitempty"`
|
||
|
||
// New poll state. Bots receive only updates about polls, which are sent or stopped by the bot
|
||
Poll *Poll `json:"poll,omitempty"`
|
||
}
|
||
|
||
// WebhookInfo contains information about the current status of a webhook.
|
||
WebhookInfo struct {
|
||
// Webhook URL, may be empty if webhook is not set up
|
||
URL string `json:"url"`
|
||
|
||
// Error message in human-readable format for the most recent error that
|
||
// happened when trying to deliver an update via webhook
|
||
LastErrorMessage string `json:"last_error_message,omitempty"`
|
||
|
||
// True, if a custom certificate was provided for webhook certificate
|
||
// checks
|
||
HasCustomCertificate bool `json:"has_custom_certificate"`
|
||
|
||
// Number of updates awaiting delivery
|
||
PendingUpdateCount int `json:"pending_update_count"`
|
||
|
||
// Maximum allowed number of simultaneous HTTPS connections to the
|
||
// webhook for update delivery
|
||
MaxConnections int `json:"max_connections,omitempty"`
|
||
|
||
// Unix time for the most recent error that happened when trying to
|
||
// deliver an update via webhook
|
||
LastErrorDate int64 `json:"last_error_date,omitempty"`
|
||
|
||
// A list of update types the bot is subscribed to. Defaults to all
|
||
// update types
|
||
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
||
}
|
||
|
||
// GetUpdatesParameters represents data for GetUpdates method.
|
||
GetUpdates struct {
|
||
// Identifier of the first update to be returned. Must be greater by one than the highest among the
|
||
// identifiers of previously received updates. By default, updates starting with the earliest unconfirmed
|
||
// update are returned. An update is considered confirmed as soon as getUpdates is called with an offset
|
||
// higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset
|
||
// update from the end of the updates queue. All previous updates will forgotten.
|
||
Offset int `json:"offset,omitempty"`
|
||
|
||
// Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100.
|
||
Limit int `json:"limit,omitempty"`
|
||
|
||
// Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short
|
||
// polling should be used for testing purposes only.
|
||
Timeout int `json:"timeout,omitempty"`
|
||
|
||
// List the types of updates you want your bot to receive. For example, specify ["message",
|
||
// "edited_channel_post", "callback_query"] to only receive updates of these types. See Update for a complete
|
||
// list of available update types. Specify an empty list to receive all updates regardless of type (default).
|
||
// If not specified, the previous setting will be used.
|
||
//
|
||
// Please note that this parameter doesn't affect updates created before the call to the getUpdates, so
|
||
// unwanted updates may be received for a short period of time.
|
||
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
||
}
|
||
|
||
// SetWebhookParameters represents data for SetWebhook method.
|
||
SetWebhook struct {
|
||
// HTTPS url to send updates to. Use an empty string to remove webhook
|
||
// integration
|
||
URL string `json:"url"`
|
||
|
||
// Upload your public key certificate so that the root certificate in use can
|
||
// be checked. See our self-signed guide for details.
|
||
Certificate InputFile `json:"certificate,omitempty"`
|
||
|
||
// Maximum allowed number of simultaneous HTTPS connections to the webhook
|
||
// for update delivery, 1-100. Defaults to 40. Use lower values to limit the
|
||
// load on your bot‘s server, and higher values to increase your bot’s
|
||
// throughput.
|
||
MaxConnections int `json:"max_connections,omitempty"`
|
||
|
||
// List the types of updates you want your bot to receive. For example,
|
||
// specify [“message”, “edited_channel_post”, “callback_query”] to only
|
||
// receive updates of these types. See Update for a complete list of
|
||
// available update types. Specify an empty list to receive all updates
|
||
// regardless of type (default). If not specified, the previous setting will
|
||
// be used.
|
||
//
|
||
// Please note that this parameter doesn't affect updates created before the
|
||
// call to the setWebhook, so unwanted updates may be received for a short
|
||
// period of time.
|
||
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
||
}
|
||
)
|
||
|
||
// GetUpdates receive incoming updates using long polling. An Array of Update objects is returned.
|
||
func (b *Bot) GetUpdates(p *GetUpdates) ([]*Update, error) {
|
||
src, err := b.Do(MethodGetUpdates, p)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
resp := new(Response)
|
||
if err = b.marshler.Unmarshal(src, resp); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
result := make([]*Update, 0)
|
||
if err = b.marshler.Unmarshal(resp.Result, &result); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// SetWebhook specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns true.
|
||
//
|
||
// If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the URL, e.g. https://www.example.com/<token>. Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
|
||
func (b *Bot) SetWebhook(p SetWebhook) (bool, error) {
|
||
var src []byte
|
||
var err error
|
||
|
||
// if p.Certificate != nil {
|
||
// src, err = b.Upload(MethodSetWebhook, "certificate", "cert.pem", params.Certificate, args)
|
||
// } else {
|
||
src, err = b.Do(MethodSetWebhook, p)
|
||
// }
|
||
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
resp := new(Response)
|
||
if err = b.marshler.Unmarshal(src, resp); err != nil {
|
||
return false, err
|
||
}
|
||
|
||
var result bool
|
||
if err = b.marshler.Unmarshal(resp.Result, &result); err != nil {
|
||
return false, err
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// DeleteWebhook remove webhook integration if you decide to switch back to getUpdates. Returns True on success. Requires no parameters.
|
||
func (b *Bot) DeleteWebhook() (bool, error) {
|
||
src, err := b.Do(MethodDeleteWebhook, nil)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
resp := new(Response)
|
||
if err = b.marshler.Unmarshal(src, resp); err != nil {
|
||
return false, err
|
||
}
|
||
|
||
var result bool
|
||
if err = b.marshler.Unmarshal(resp.Result, &result); err != nil {
|
||
return false, err
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// GetWebhookInfo get current webhook status. Requires no parameters. On success, returns a WebhookInfo object. If the bot is using getUpdates, will return an object with the url field empty.
|
||
func (b *Bot) GetWebhookInfo() (*WebhookInfo, error) {
|
||
src, err := b.Do(MethodGetWebhookInfo, nil)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
resp := new(Response)
|
||
if err = b.marshler.Unmarshal(src, resp); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
result := new(WebhookInfo)
|
||
if err = b.marshler.Unmarshal(resp.Result, &result); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// IsMessage checks that the current update is a message creation event.
|
||
func (u Update) IsMessage() bool { return u.Message != nil }
|
||
|
||
// IsEditedMessage checks that the current update is a editing message event.
|
||
func (u Update) IsEditedMessage() bool { return u.EditedMessage != nil }
|
||
|
||
// IsChannelPost checks that the current update is a post channel creation event.
|
||
func (u Update) IsChannelPost() bool { return u.ChannelPost != nil }
|
||
|
||
// IsEditedChannelPost checks that the current update is a editing post channel event.
|
||
func (u Update) IsEditedChannelPost() bool { return u.EditedChannelPost != nil }
|
||
|
||
// IsInlineQuery checks that the current update is a inline query update.
|
||
func (u Update) IsInlineQuery() bool { return u.InlineQuery != nil }
|
||
|
||
// IsChosenInlineResult checks that the current update is a chosen inline result update.
|
||
func (u Update) IsChosenInlineResult() bool { return u.ChosenInlineResult != nil }
|
||
|
||
// IsCallbackQuery checks that the current update is a callback query update.
|
||
func (u Update) IsCallbackQuery() bool { return u.CallbackQuery != nil }
|
||
|
||
// IsShippingQuery checks that the current update is a shipping query update.
|
||
func (u Update) IsShippingQuery() bool { return u.ShippingQuery != nil }
|
||
|
||
// IsPreCheckoutQuery checks that the current update is a pre checkout query update.
|
||
func (u Update) IsPreCheckoutQuery() bool { return u.PreCheckoutQuery != nil }
|
||
|
||
// IsPoll checks that the current update is a poll update.
|
||
func (u Update) IsPoll() bool { return u.Poll != nil }
|
||
|
||
// Type return update type for current update.
|
||
func (u Update) Type() string {
|
||
switch {
|
||
case u.IsCallbackQuery():
|
||
return UpdateCallbackQuery
|
||
case u.IsChannelPost():
|
||
return UpdateChannelPost
|
||
case u.IsChosenInlineResult():
|
||
return UpdateChosenInlineResult
|
||
case u.IsEditedChannelPost():
|
||
return UpdateEditedChannelPost
|
||
case u.IsEditedMessage():
|
||
return UpdateEditedMessage
|
||
case u.IsInlineQuery():
|
||
return UpdateInlineQuery
|
||
case u.IsMessage():
|
||
return UpdateMessage
|
||
case u.IsPreCheckoutQuery():
|
||
return UpdatePreCheckoutQuery
|
||
case u.IsShippingQuery():
|
||
return UpdateShippingQuery
|
||
case u.IsPoll():
|
||
return UpdatePoll
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
|
||
func (wi WebhookInfo) LastErrorTime() time.Time { return time.Unix(wi.LastErrorDate, 0) }
|
||
|
||
func (wi WebhookInfo) HasURL() bool { return wi.URL != "" }
|
||
|
||
func (wi WebhookInfo) URI() *http.URI {
|
||
if !wi.HasURL() {
|
||
return nil
|
||
}
|
||
|
||
u := http.AcquireURI()
|
||
u.Update(wi.URL)
|
||
return u
|
||
}
|