Merge branch 'develop' into v2

pull/413/head
Demian 3 years ago
commit d55bccca5b

@ -21,17 +21,17 @@ type ChatInviteLink struct {
IsRevoked bool `json:"is_revoked"`
// (Optional) Point in time when the link will expire, use
// ChatInviteLink.ExpireTime() to get time.Time
Unixtime int64 `json:"expire_date,omitempty"`
// ChatInviteLink.ExpireDate() to get time.Time
ExpireUnixtime int64 `json:"expire_date,omitempty"`
// (Optional) Maximum number of users that can be members of
// the chat simultaneously.
MemberLimit int `json:"member_limit,omitempty"`
}
// ExpireTime returns the moment of the link expiration in local time.
func (c *ChatInviteLink) ExpireTime() time.Time {
return time.Unix(c.Unixtime, 0)
// ExpireDate returns the moment of the link expiration in local time.
func (c *ChatInviteLink) ExpireDate() time.Time {
return time.Unix(c.ExpireUnixtime, 0)
}
// ChatMemberUpdated object represents changes in the status of a chat member.
@ -40,7 +40,7 @@ type ChatMemberUpdated struct {
Chat Chat `json:"chat"`
// From which user the action was triggered.
From User `json:"user"`
From User `json:"from"`
// Unixtime, use ChatMemberUpdated.Time() to get time.Time
Unixtime int64 `json:"date"`
@ -51,9 +51,9 @@ type ChatMemberUpdated struct {
// New information about the chat member.
NewChatMember *ChatMember `json:"new_chat_member"`
// (Optional) ChatInviteLink which was used by the user to
// (Optional) InviteLink which was used by the user to
// join the chat; for joining by invite link events only.
ChatInviteLink *ChatInviteLink `json:"chat_invite_link"`
InviteLink *ChatInviteLink `json:"invite_link"`
}
// Time returns the moment of the change in local time.
@ -78,6 +78,7 @@ type Rights struct {
CanSendOther bool `json:"can_send_other_messages"`
CanAddPreviews bool `json:"can_add_web_page_previews"`
CanManageVoiceChats bool `json:"can_manage_voice_chats"`
CanManageChat bool `json:"can_manage_chat"`
}
// NoRights is the default Rights{}.
@ -106,6 +107,7 @@ func NoRestrictions() Rights {
CanSendOther: true,
CanAddPreviews: true,
CanManageVoiceChats: false,
CanManageChat: false,
}
}
@ -127,33 +129,42 @@ func AdminRights() Rights {
CanSendOther: true,
CanAddPreviews: true,
CanManageVoiceChats: true,
CanManageChat: true,
}
}
// Forever is a Unixtime of "forever" banning.
// Forever is a ExpireUnixtime of "forever" banning.
func Forever() int64 {
return time.Now().Add(367 * 24 * time.Hour).Unix()
}
// Ban will ban user from chat until `member.RestrictedUntil`.
func (b *Bot) Ban(chat *Chat, member *ChatMember) error {
func (b *Bot) Ban(chat *Chat, member *ChatMember, revokeMessages ...bool) error {
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
"until_date": strconv.FormatInt(member.RestrictedUntil, 10),
}
if len(revokeMessages) > 0 {
params["revoke_messages"] = strconv.FormatBool(revokeMessages[0])
}
_, err := b.Raw("kickChatMember", params)
return err
}
// Unban will unban user from chat, who would have thought eh?
func (b *Bot) Unban(chat *Chat, user *User) error {
// forBanned does nothing if the user is not banned.
func (b *Bot) Unban(chat *Chat, user *User, forBanned ...bool) error {
params := map[string]string{
"chat_id": chat.Recipient(),
"user_id": user.Recipient(),
}
if len(forBanned) > 0 {
params["only_if_banned"] = strconv.FormatBool(forBanned[0])
}
_, err := b.Raw("unbanChatMember", params)
return err
}
@ -195,8 +206,9 @@ func (b *Bot) Promote(chat *Chat, member *ChatMember) error {
prv := member.Rights
params := map[string]interface{}{
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
"chat_id": chat.Recipient(),
"user_id": member.User.Recipient(),
"is_anonymous": member.Anonymous,
}
embedRights(params, prv)

203
bot.go

@ -336,11 +336,50 @@ func (b *Bot) ProcessUpdate(upd Update) {
return
}
if m.VoiceChatPartecipantsInvited != nil {
if handler, ok := b.handlers[OnVoiceChatPartecipantsInvited]; ok {
if m.VoiceChatParticipantsInvited != nil {
if handler, ok := b.handlers[OnVoiceChatParticipantsInvited]; ok {
handler, ok := handler.(func(*Message))
if !ok {
panic("telebot: voice chat partecipants invited handler is bad")
panic("telebot: voice chat participants invited handler is bad")
}
b.runHandler(func() { handler(m) })
}
return
}
if m.ProximityAlert != nil {
if handler, ok := b.handlers[OnProximityAlert]; ok {
handler, ok := handler.(func(*Message))
if !ok {
panic("telebot: proximity alert handler is bad")
}
b.runHandler(func() { handler(m) })
}
return
}
if m.AutoDeleteTimer != nil {
if handler, ok := b.handlers[OnAutoDeleteTimer]; ok {
handler, ok := handler.(func(*Message))
if !ok {
panic("telebot: auto delete timer handler is bad")
}
b.runHandler(func() { handler(m) })
}
return
}
if m.VoiceChatSchedule != nil {
if handler, ok := b.handlers[OnVoiceChatScheduled]; ok {
handler, ok := handler.(func(*Message))
if !ok {
panic("telebot: voice chat scheduled is bad")
}
b.runHandler(func() { handler(m) })
@ -510,10 +549,10 @@ func (b *Bot) ProcessUpdate(upd Update) {
if handler, ok := b.handlers[OnChatMember]; ok {
handler, ok := handler.(func(*ChatMemberUpdated))
if !ok {
panic("telebot: my chat member handler is bad")
panic("telebot: chat member handler is bad")
}
b.runHandler(func() { handler(upd.MyChatMember) })
b.runHandler(func() { handler(upd.ChatMember) })
}
return
@ -741,6 +780,32 @@ func (b *Bot) Forward(to Recipient, msg Editable, options ...interface{}) (*Mess
return extractMessage(data)
}
// Copy behaves just like Forward() but the copied message doesn't have a link to the original message (see Bots API).
//
// This function will panic upon nil Editable.
func (b *Bot) Copy(to Recipient, msg Editable, options ...interface{}) (*Message, error) {
if to == nil {
return nil, ErrBadRecipient
}
msgID, chatID := msg.MessageSig()
params := map[string]string{
"chat_id": to.Recipient(),
"from_chat_id": strconv.FormatInt(chatID, 10),
"message_id": msgID,
}
sendOpts := extractOptions(options)
b.embedSendOptions(params, sendOpts)
data, err := b.Raw("copyMessage", params)
if err != nil {
return nil, err
}
return extractMessage(data)
}
// Edit is magic, it lets you change already sent message.
//
// If edited message is sent by the bot, returns it,
@ -773,6 +838,15 @@ func (b *Bot) Edit(msg Editable, what interface{}, options ...interface{}) (*Mes
method = "editMessageLiveLocation"
params["latitude"] = fmt.Sprintf("%f", v.Lat)
params["longitude"] = fmt.Sprintf("%f", v.Lng)
if v.HorizontalAccuracy != nil {
params["horizontal_accuracy"] = fmt.Sprintf("%f", *v.HorizontalAccuracy)
}
if v.Heading != 0 {
params["heading"] = strconv.Itoa(v.Heading)
}
if v.ProximityAlertRadius != 0 {
params["proximity_alert_radius"] = strconv.Itoa(v.Heading)
}
default:
return nil, ErrUnsupportedWhat
}
@ -1395,15 +1469,31 @@ func (b *Bot) Pin(msg Editable, options ...interface{}) error {
// Unpin unpins a message in a supergroup or a channel.
//
// It supports tb.Silent option.
func (b *Bot) Unpin(chat *Chat) error {
// MessageID is a specific pinned message
func (b *Bot) Unpin(chat *Chat, messageID ...int) error {
params := map[string]string{
"chat_id": chat.Recipient(),
}
if len(messageID) > 0 {
params["message_id"] = strconv.Itoa(messageID[0])
}
_, err := b.Raw("unpinChatMessage", params)
return err
}
// UnpinAll unpins all messages in a supergroup or a channel.
//
// It supports tb.Silent option.
func (b *Bot) UnpinAll(chat *Chat) error {
params := map[string]string{
"chat_id": chat.Recipient(),
}
_, err := b.Raw("unpinAllChatMessages", params)
return err
}
// ChatByID fetches chat info of its ID.
//
// Including current name of the user for one-on-one conversations,
@ -1526,3 +1616,104 @@ func (b *Bot) SetCommands(cmds []Command) error {
func (b *Bot) NewMarkup() *ReplyMarkup {
return &ReplyMarkup{}
}
// Logout logs out from the cloud Bot API server before launching the bot locally.
func (b *Bot) Logout() (bool, error) {
data, err := b.Raw("logOut", nil)
if err != nil {
return false, err
}
var resp struct {
Result bool `json:"result"`
}
if err := json.Unmarshal(data, &resp); err != nil {
return false, wrapError(err)
}
return resp.Result, nil
}
// Close closes the bot instance before moving it from one local server to another.
func (b *Bot) Close() (bool, error) {
data, err := b.Raw("close", nil)
if err != nil {
return false, err
}
var resp struct {
Result bool `json:"result"`
}
if err := json.Unmarshal(data, &resp); err != nil {
return false, wrapError(err)
}
return resp.Result, nil
}
// CreateInviteLink creates an additional invite link for a chat.
func (b *Bot) CreateInviteLink(chat *Chat, link *ChatInviteLink) (*ChatInviteLink, error) {
params := map[string]string{
"chat_id": chat.Recipient(),
}
if link != nil {
params["expire_date"] = strconv.FormatInt(link.ExpireUnixtime, 10)
params["member_limit"] = strconv.Itoa(link.MemberLimit)
}
data, err := b.Raw("createChatInviteLink", params)
if err != nil {
return nil, err
}
var resp ChatInviteLink
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return &resp, nil
}
// EditInviteLink edits a non-primary invite link created by the bot.
func (b *Bot) EditInviteLink(chat *Chat, link *ChatInviteLink) (*ChatInviteLink, error) {
params := map[string]string{
"chat_id": chat.Recipient(),
}
if link != nil {
params["invite_link"] = link.InviteLink
params["expire_date"] = strconv.FormatInt(link.ExpireUnixtime, 10)
params["member_limit"] = strconv.Itoa(link.MemberLimit)
}
data, err := b.Raw("editChatInviteLink", params)
if err != nil {
return nil, err
}
var resp ChatInviteLink
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return &resp, nil
}
// RevokeInviteLink revokes an invite link created by the bot.
func (b *Bot) RevokeInviteLink(chat *Chat, link string) (*ChatInviteLink, error) {
params := map[string]string{
"chat_id": chat.Recipient(),
"link": link,
}
data, err := b.Raw("revokeChatInviteLink", params)
if err != nil {
return nil, err
}
var resp ChatInviteLink
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return &resp, nil
}

@ -42,14 +42,22 @@ type Chat struct {
Still bool `json:"is_member,omitempty"`
// Returns only in getChat
Photo *ChatPhoto `json:"photo,omitempty"`
Description string `json:"description,omitempty"`
InviteLink string `json:"invite_link,omitempty"`
PinnedMessage *Message `json:"pinned_message,omitempty"`
Permissions *Rights `json:"permissions,omitempty"`
SlowMode int `json:"slow_mode_delay,omitempty"`
StickerSet string `json:"sticker_set_name,omitempty"`
CanSetStickerSet bool `json:"can_set_sticker_set,omitempty"`
Bio string `json:"bio,omitempty"`
Photo *ChatPhoto `json:"photo,omitempty"`
Description string `json:"description,omitempty"`
InviteLink string `json:"invite_link,omitempty"`
PinnedMessage *Message `json:"pinned_message,omitempty"`
Permissions *Rights `json:"permissions,omitempty"`
SlowMode int `json:"slow_mode_delay,omitempty"`
StickerSet string `json:"sticker_set_name,omitempty"`
CanSetStickerSet bool `json:"can_set_sticker_set,omitempty"`
LinkedChatID int64 `json:"linked_chat_id,omitempty"`
ChatLocation *ChatLocation `json:"location,omitempty"`
}
type ChatLocation struct {
Location Location `json:"location,omitempty"`
Address string `json:"address,omitempty"`
}
// ChatPhoto object represents a chat photo.
@ -72,9 +80,10 @@ func (c *Chat) Recipient() string {
type ChatMember struct {
Rights
User *User `json:"user"`
Role MemberStatus `json:"status"`
Title string `json:"custom_title"`
User *User `json:"user"`
Role MemberStatus `json:"status"`
Title string `json:"custom_title"`
Anonymous bool `json:"is_anonymous"`
// Date when restrictions will be lifted for the user, unix time.
//

@ -9,6 +9,7 @@ import (
type File struct {
FileID string `json:"file_id"`
UniqueID string `json:"file_unique_id"`
FileName string `json:"file_name"`
FileSize int `json:"file_size"`
// file on telegram server https://core.telegram.org/bots/api#file

@ -33,6 +33,9 @@ type Query struct {
// Offset of the results to be returned, can be controlled by the bot.
Offset string `json:"offset"`
// ChatType of the type of the chat, from which the inline query was sent.
ChatType string `json:"chat_type"`
}
// QueryResponse builds a response to an inline Query.

@ -195,9 +195,24 @@ type Location struct {
// Longitude
Lng float32 `json:"longitude"`
// Horizontal Accuracy
HorizontalAccuracy *float32 `json:"horizontal_accuracy,omitempty"`
Heading int `json:"heading,omitempty"`
// Period in seconds for which the location will be updated
// (see Live Locations, should be between 60 and 86400.)
LivePeriod int `json:"live_period,omitempty"`
ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"`
}
// ProximityAlertTriggered sent whenever
// a user in the chat triggers a proximity alert set by another user.
type ProximityAlertTriggered struct {
Traveler *User `json:"traveler,omitempty"`
Watcher *User `json:"watcher,omitempty"`
Distance int `json:"distance"`
}
// Venue object represents a venue location with name, address and
@ -208,8 +223,10 @@ type Venue struct {
Address string `json:"address"`
// (Optional)
FoursquareID string `json:"foursquare_id,omitempty"`
FoursquareType string `json:"foursquare_type,omitempty"`
FoursquareID string `json:"foursquare_id,omitempty"`
FoursquareType string `json:"foursquare_type,omitempty"`
GooglePlaceID string `json:"google_place_id,omitempty"`
GooglePlaceType string `json:"google_place_type,omitempty"`
}
// Dice object represents a dice with a random value

@ -20,6 +20,9 @@ type Message struct {
// Conversation the message belongs to.
Chat *Chat `json:"chat"`
// Sender of the message, sent on behalf of a chat.
SenderChat *Chat `json:"sender_chat"`
// For forwarded messages, sender of the original message.
OriginalSender *User `json:"forward_from"`
@ -218,6 +221,8 @@ type Message struct {
// Inline keyboard attached to the message.
ReplyMarkup InlineKeyboardMarkup `json:"reply_markup"`
VoiceChatSchedule *VoiceChatScheduled `json:"voice_chat_scheduled,omitempty"`
// For a service message, a voice chat started in the chat.
VoiceChatStarted *VoiceChatStarted `json:"voice_chat_started,omitempty"`
@ -225,7 +230,19 @@ type Message struct {
VoiceChatEnded *VoiceChatEnded `json:"voice_chat_ended,omitempty"`
// For a service message, some users were invited in the voice chat.
VoiceChatPartecipantsInvited *VoiceChatPartecipantsInvited `json:"voice_chat_partecipants_invited,omitempty"`
VoiceChatParticipantsInvited *VoiceChatParticipantsInvited `json:"voice_chat_participants_invited,omitempty"`
// For a service message, represents the content of a service message,
// sent whenever a user in the chat triggers a proximity alert set by another user.
ProximityAlert *ProximityAlertTriggered `json:"proximity_alert_triggered,omitempty"`
// For a service message, represents about a change in auto-delete timer settings.
AutoDeleteTimer *MessageAutoDeleteTimerChanged `json:"message_auto_delete_timer_changed,omitempty"`
}
// MessageAutoDeleteTimerChanged represents a service message about a change in auto-delete timer settings.
type MessageAutoDeleteTimerChanged struct {
DeleteTime int `json:"message_auto_delete_time"`
}
// MessageEntity object represents "special" parts of text messages,

@ -50,6 +50,12 @@ type SendOptions struct {
// ParseMode controls how client apps render your message.
ParseMode ParseMode
// DisableContentDetection abilities to disable server-side file content type detection.
DisableContentDetection bool
// AllowWithoutReply allows sending messages not a as reply if the replied-to message has already been deleted.
AllowWithoutReply bool
}
func (og *SendOptions) copy() *SendOptions {

@ -74,13 +74,16 @@ type Invoice struct {
PhotoSize int `json:"photo_size"`
// Unique deep-linking parameter that can be used to
// generate this invoice when used as a start parameter.
// generate this invoice when used as a start parameter (0).
Start string `json:"start_parameter"`
// Shows the total price in the smallest units of the currency.
// For example, for a price of US$ 1.45 pass amount = 145.
Total int `json:"total_amount"`
MaxTipAmount int `json:"max_tip_amount"`
SuggestedTipAmounts []int `json:"suggested_tip_amounts"`
NeedName bool `json:"need_name"`
NeedPhoneNumber bool `json:"need_phone_number"`
NeedEmail bool `json:"need_email"`

@ -5,6 +5,7 @@ import (
"fmt"
"path/filepath"
"strconv"
"strings"
)
// Recipient is any possible endpoint you can send
@ -265,6 +266,15 @@ func (x *Location) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error
"longitude": fmt.Sprintf("%f", x.Lng),
"live_period": strconv.Itoa(x.LivePeriod),
}
if x.HorizontalAccuracy != nil {
params["horizontal_accuracy"] = fmt.Sprintf("%f", *x.HorizontalAccuracy)
}
if x.Heading != 0 {
params["heading"] = strconv.Itoa(x.Heading)
}
if x.ProximityAlertRadius != 0 {
params["proximity_alert_radius"] = strconv.Itoa(x.Heading)
}
b.embedSendOptions(params, opt)
data, err := b.Raw("sendLocation", params)
@ -278,13 +288,15 @@ func (x *Location) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error
// Send delivers media through bot b to recipient.
func (v *Venue) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"latitude": fmt.Sprintf("%f", v.Location.Lat),
"longitude": fmt.Sprintf("%f", v.Location.Lng),
"title": v.Title,
"address": v.Address,
"foursquare_id": v.FoursquareID,
"foursquare_type": v.FoursquareType,
"chat_id": to.Recipient(),
"latitude": fmt.Sprintf("%f", v.Location.Lat),
"longitude": fmt.Sprintf("%f", v.Location.Lng),
"title": v.Title,
"address": v.Address,
"foursquare_id": v.FoursquareID,
"foursquare_type": v.FoursquareType,
"google_place_id": v.GooglePlaceID,
"google_place_type": v.GooglePlaceType,
}
b.embedSendOptions(params, opt)
@ -306,6 +318,7 @@ func (i *Invoice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error)
"payload": i.Payload,
"provider_token": i.Token,
"currency": i.Currency,
"max_tip_amount": strconv.Itoa(i.MaxTipAmount),
"need_name": strconv.FormatBool(i.NeedName),
"need_phone_number": strconv.FormatBool(i.NeedPhoneNumber),
"need_email": strconv.FormatBool(i.NeedEmail),
@ -332,6 +345,9 @@ func (i *Invoice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error)
data, _ := json.Marshal(i.Prices)
params["prices"] = string(data)
}
if len(i.SuggestedTipAmounts) > 0 {
params["suggested_tip_amounts"] = "[" + strings.Join(intsToStrs(i.SuggestedTipAmounts), ",") + "]"
}
b.embedSendOptions(params, opt)
data, err := b.Raw("sendInvoice", params)

@ -140,10 +140,25 @@ const (
// Handler: func(*Message)
OnVoiceChatEnded = "\avoice_chat_ended"
// Will fire on VoiceChatPartecipantsInvited
// Will fire on VoiceChatParticipantsInvited
//
// Handler: func(*Message)
OnVoiceChatPartecipantsInvited = "\avoice_chat_partecipants_invited"
OnVoiceChatParticipantsInvited = "\avoice_chat_participants_invited"
// Will fire on ProximityAlert
//
// Handler: func(*Message)
OnProximityAlert = "\aproximity_alert_triggered"
// Will fire on AudoDeleteTimer
//
// Handler: func(*Message)
OnAutoDeleteTimer = "\amessage_auto_delete_timer_changed"
// Will fire on OnVoiceChatScheduled
//
// Handler: func(*Message)
OnVoiceChatScheduled = "\avoice_chat_scheduled"
)
// ChatAction is a client-side status indicating bot activity.

@ -1,13 +1,13 @@
package telebot
import (
"bytes"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"log"
"net/http"
"strconv"
"bytes"
"github.com/pkg/errors"
)
func (b *Bot) debug(err error) {
@ -195,6 +195,14 @@ func (b *Bot) embedSendOptions(params map[string]string, opt *SendOptions) {
params["parse_mode"] = opt.ParseMode
}
if opt.DisableContentDetection {
params["disable_content_type_detection"] = "true"
}
if opt.AllowWithoutReply {
params["allow_sending_without_reply"] = "true"
}
if opt.ReplyMarkup != nil {
processButtons(opt.ReplyMarkup.InlineKeyboard)
replyMarkup, _ := json.Marshal(opt.ReplyMarkup)
@ -243,3 +251,10 @@ func isUserInList(user *User, list []User) bool {
}
return false
}
func intsToStrs(ns []int) (s []string) {
for _, n := range ns {
s = append(s, strconv.Itoa(n))
}
return
}

@ -60,6 +60,7 @@ func TestEmbedRights(t *testing.T) {
"can_pin_messages": false,
"can_promote_members": false,
"can_manage_voice_chats": false,
"can_manage_chat": false,
}
assert.Equal(t, expected, params)
}

@ -0,0 +1,29 @@
package telebot
import "time"
// VoiceChatStarted represents a service message about a voice chat
// started in the chat.
type VoiceChatStarted struct{}
// VoiceChatEnded represents a service message about a voice chat
// ended in the chat.
type VoiceChatEnded struct {
Duration int `json:"duration"`
}
// VoiceChatParticipantsInvited represents a service message about new
// members invited to a voice chat
type VoiceChatParticipantsInvited struct {
Users []User `json:"users"`
}
// VoiceChatScheduled represents a service message about a voice chat scheduled in the chat.
type VoiceChatScheduled struct {
Unixtime int64 `json:"start_date"`
}
// ExpireDate returns the point when the voice chat is supposed to be started by a chat administrator.
func (v *VoiceChatScheduled) ExpireDate() time.Time {
return time.Unix(v.Unixtime, 0)
}

@ -1,17 +0,0 @@
package telebot
// VoiceChatStarted represents a service message about a voice chat
// started in the chat.
type VoiceChatStarted struct{}
// VoiceChatEnded represents a service message about a voice chat
// ended in the chat.
type VoiceChatEnded struct {
Duration int `json:"duration"`
}
// VoiceChatPartecipantsInvited represents a service message about new
// members invited to a voice chat
type VoiceChatPartecipantsInvited struct {
Users []User `json:"users"`
}

@ -49,6 +49,9 @@ type Webhook struct {
ErrorUnixtime int64 `json:"last_error_date"`
ErrorMessage string `json:"last_error_message"`
IP string `json:"ip_address"`
DropUpdates bool `json:"drop_pending_updates"`
TLS *WebhookTLS
Endpoint *WebhookEndpoint
@ -88,6 +91,12 @@ func (h *Webhook) getParams() map[string]string {
data, _ := json.Marshal(h.AllowedUpdates)
params["allowed_updates"] = string(data)
}
if h.IP != "" {
params["ip_address"] = h.IP
}
if h.DropUpdates {
params["drop_pending_updates"] = strconv.FormatBool(h.DropUpdates)
}
if h.TLS != nil {
params["url"] = "https://" + h.Listen
@ -178,7 +187,13 @@ func (b *Bot) SetWebhook(w *Webhook) error {
}
// RemoveWebhook removes webhook integration.
func (b *Bot) RemoveWebhook() error {
_, err := b.Raw("deleteWebhook", nil)
func (b *Bot) RemoveWebhook(dropPending ...bool) error {
drop := false
if len(dropPending) > 0 {
drop = dropPending[0]
}
_, err := b.Raw("deleteWebhook", map[string]bool{
"drop_pending_updates": drop,
})
return err
}

Loading…
Cancel
Save