upgrade telegram api.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
fd0eb0f6c1
commit
3ef45379c4
276
vendor/gopkg.in/telegram-bot-api.v4/bot.go
generated
vendored
276
vendor/gopkg.in/telegram-bot-api.v4/bot.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/technoweenie/multipartstreamer"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -16,12 +16,16 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/technoweenie/multipartstreamer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BotAPI allows you to interact with the Telegram Bot API.
|
// BotAPI allows you to interact with the Telegram Bot API.
|
||||||
type BotAPI struct {
|
type BotAPI struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
|
Buffer int `json:"buffer"`
|
||||||
|
|
||||||
Self User `json:"-"`
|
Self User `json:"-"`
|
||||||
Client *http.Client `json:"-"`
|
Client *http.Client `json:"-"`
|
||||||
}
|
}
|
||||||
@ -41,11 +45,12 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
|
|||||||
bot := &BotAPI{
|
bot := &BotAPI{
|
||||||
Token: token,
|
Token: token,
|
||||||
Client: client,
|
Client: client,
|
||||||
|
Buffer: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
self, err := bot.GetMe()
|
self, err := bot.GetMe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &BotAPI{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.Self = self
|
bot.Self = self
|
||||||
@ -63,29 +68,47 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse,
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusForbidden {
|
var apiResp APIResponse
|
||||||
return APIResponse{}, errors.New(ErrAPIForbidden)
|
bytes, err := bot.decodeAPIResponse(resp.Body, &apiResp)
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIResponse{}, err
|
return apiResp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if bot.Debug {
|
if bot.Debug {
|
||||||
log.Println(endpoint, string(bytes))
|
log.Printf("%s resp: %s", endpoint, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiResp APIResponse
|
|
||||||
json.Unmarshal(bytes, &apiResp)
|
|
||||||
|
|
||||||
if !apiResp.Ok {
|
if !apiResp.Ok {
|
||||||
return APIResponse{}, errors.New(apiResp.Description)
|
return apiResp, errors.New(apiResp.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiResp, nil
|
return apiResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decodeAPIResponse decode response and return slice of bytes if debug enabled.
|
||||||
|
// If debug disabled, just decode http.Response.Body stream to APIResponse struct
|
||||||
|
// for efficient memory usage
|
||||||
|
func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse) (_ []byte, err error) {
|
||||||
|
if !bot.Debug {
|
||||||
|
dec := json.NewDecoder(responseBody)
|
||||||
|
err = dec.Decode(resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if debug, read reponse body
|
||||||
|
data, err := ioutil.ReadAll(responseBody)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, resp)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// makeMessageRequest makes a request to a method that returns a Message.
|
// makeMessageRequest makes a request to a method that returns a Message.
|
||||||
func (bot *BotAPI) makeMessageRequest(endpoint string, params url.Values) (Message, error) {
|
func (bot *BotAPI) makeMessageRequest(endpoint string, params url.Values) (Message, error) {
|
||||||
resp, err := bot.MakeRequest(endpoint, params)
|
resp, err := bot.MakeRequest(endpoint, params)
|
||||||
@ -183,7 +206,11 @@ func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldna
|
|||||||
}
|
}
|
||||||
|
|
||||||
var apiResp APIResponse
|
var apiResp APIResponse
|
||||||
json.Unmarshal(bytes, &apiResp)
|
|
||||||
|
err = json.Unmarshal(bytes, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
return APIResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
if !apiResp.Ok {
|
if !apiResp.Ok {
|
||||||
return APIResponse{}, errors.New(apiResp.Description)
|
return APIResponse{}, errors.New(apiResp.Description)
|
||||||
@ -408,29 +435,29 @@ func (bot *BotAPI) RemoveWebhook() (APIResponse, error) {
|
|||||||
// If you do not have a legitimate TLS certificate, you need to include
|
// If you do not have a legitimate TLS certificate, you need to include
|
||||||
// your self signed certificate with the config.
|
// your self signed certificate with the config.
|
||||||
func (bot *BotAPI) SetWebhook(config WebhookConfig) (APIResponse, error) {
|
func (bot *BotAPI) SetWebhook(config WebhookConfig) (APIResponse, error) {
|
||||||
|
|
||||||
if config.Certificate == nil {
|
if config.Certificate == nil {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
v.Add("url", config.URL.String())
|
v.Add("url", config.URL.String())
|
||||||
|
if config.MaxConnections != 0 {
|
||||||
|
v.Add("max_connections", strconv.Itoa(config.MaxConnections))
|
||||||
|
}
|
||||||
|
|
||||||
return bot.MakeRequest("setWebhook", v)
|
return bot.MakeRequest("setWebhook", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
params := make(map[string]string)
|
params := make(map[string]string)
|
||||||
params["url"] = config.URL.String()
|
params["url"] = config.URL.String()
|
||||||
|
if config.MaxConnections != 0 {
|
||||||
|
params["max_connections"] = strconv.Itoa(config.MaxConnections)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := bot.UploadFile("setWebhook", params, "certificate", config.Certificate)
|
resp, err := bot.UploadFile("setWebhook", params, "certificate", config.Certificate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIResponse{}, err
|
return APIResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiResp APIResponse
|
return resp, nil
|
||||||
json.Unmarshal(resp.Result, &apiResp)
|
|
||||||
|
|
||||||
if bot.Debug {
|
|
||||||
log.Printf("setWebhook resp: %+v\n", apiResp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiResp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookInfo allows you to fetch information about a webhook and if
|
// GetWebhookInfo allows you to fetch information about a webhook and if
|
||||||
@ -448,8 +475,8 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUpdatesChan starts and returns a channel for getting updates.
|
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||||
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (<-chan Update, error) {
|
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) {
|
||||||
updatesChan := make(chan Update, 100)
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -465,18 +492,18 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (<-chan Update, error) {
|
|||||||
for _, update := range updates {
|
for _, update := range updates {
|
||||||
if update.UpdateID >= config.Offset {
|
if update.UpdateID >= config.Offset {
|
||||||
config.Offset = update.UpdateID + 1
|
config.Offset = update.UpdateID + 1
|
||||||
updatesChan <- update
|
ch <- update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return updatesChan, nil
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenForWebhook registers a http handler for a webhook.
|
// ListenForWebhook registers a http handler for a webhook.
|
||||||
func (bot *BotAPI) ListenForWebhook(pattern string) <-chan Update {
|
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||||
updatesChan := make(chan Update, 100)
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
bytes, _ := ioutil.ReadAll(r.Body)
|
bytes, _ := ioutil.ReadAll(r.Body)
|
||||||
@ -484,10 +511,10 @@ func (bot *BotAPI) ListenForWebhook(pattern string) <-chan Update {
|
|||||||
var update Update
|
var update Update
|
||||||
json.Unmarshal(bytes, &update)
|
json.Unmarshal(bytes, &update)
|
||||||
|
|
||||||
updatesChan <- update
|
ch <- update
|
||||||
})
|
})
|
||||||
|
|
||||||
return updatesChan
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnswerInlineQuery sends a response to an inline query.
|
// AnswerInlineQuery sends a response to an inline query.
|
||||||
@ -535,7 +562,7 @@ func (bot *BotAPI) AnswerCallbackQuery(config CallbackConfig) (APIResponse, erro
|
|||||||
// KickChatMember kicks a user from a chat. Note that this only will work
|
// KickChatMember kicks a user from a chat. Note that this only will work
|
||||||
// in supergroups, and requires the bot to be an admin. Also note they
|
// in supergroups, and requires the bot to be an admin. Also note they
|
||||||
// will be unable to rejoin until they are unbanned.
|
// will be unable to rejoin until they are unbanned.
|
||||||
func (bot *BotAPI) KickChatMember(config ChatMemberConfig) (APIResponse, error) {
|
func (bot *BotAPI) KickChatMember(config KickChatMemberConfig) (APIResponse, error) {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
|
|
||||||
if config.SuperGroupUsername == "" {
|
if config.SuperGroupUsername == "" {
|
||||||
@ -545,6 +572,10 @@ func (bot *BotAPI) KickChatMember(config ChatMemberConfig) (APIResponse, error)
|
|||||||
}
|
}
|
||||||
v.Add("user_id", strconv.Itoa(config.UserID))
|
v.Add("user_id", strconv.Itoa(config.UserID))
|
||||||
|
|
||||||
|
if config.UntilDate != 0 {
|
||||||
|
v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
|
||||||
|
}
|
||||||
|
|
||||||
bot.debugLog("kickChatMember", v, nil)
|
bot.debugLog("kickChatMember", v, nil)
|
||||||
|
|
||||||
return bot.MakeRequest("kickChatMember", v)
|
return bot.MakeRequest("kickChatMember", v)
|
||||||
@ -662,14 +693,16 @@ func (bot *BotAPI) GetChatMember(config ChatConfigWithUser) (ChatMember, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnbanChatMember unbans a user from a chat. Note that this only will work
|
// UnbanChatMember unbans a user from a chat. Note that this only will work
|
||||||
// in supergroups, and requires the bot to be an admin.
|
// in supergroups and channels, and requires the bot to be an admin.
|
||||||
func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error) {
|
func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error) {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
|
|
||||||
if config.SuperGroupUsername == "" {
|
if config.SuperGroupUsername != "" {
|
||||||
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
|
||||||
} else {
|
|
||||||
v.Add("chat_id", config.SuperGroupUsername)
|
v.Add("chat_id", config.SuperGroupUsername)
|
||||||
|
} else if config.ChannelUsername != "" {
|
||||||
|
v.Add("chat_id", config.ChannelUsername)
|
||||||
|
} else {
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
}
|
}
|
||||||
v.Add("user_id", strconv.Itoa(config.UserID))
|
v.Add("user_id", strconv.Itoa(config.UserID))
|
||||||
|
|
||||||
@ -678,6 +711,86 @@ func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error)
|
|||||||
return bot.MakeRequest("unbanChatMember", v)
|
return bot.MakeRequest("unbanChatMember", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RestrictChatMember to restrict a user in a supergroup. The bot must be an
|
||||||
|
//administrator in the supergroup for this to work and must have the
|
||||||
|
//appropriate admin rights. Pass True for all boolean parameters to lift
|
||||||
|
//restrictions from a user. Returns True on success.
|
||||||
|
func (bot *BotAPI) RestrictChatMember(config RestrictChatMemberConfig) (APIResponse, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
if config.SuperGroupUsername != "" {
|
||||||
|
v.Add("chat_id", config.SuperGroupUsername)
|
||||||
|
} else if config.ChannelUsername != "" {
|
||||||
|
v.Add("chat_id", config.ChannelUsername)
|
||||||
|
} else {
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
}
|
||||||
|
v.Add("user_id", strconv.Itoa(config.UserID))
|
||||||
|
|
||||||
|
if &config.CanSendMessages != nil {
|
||||||
|
v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages))
|
||||||
|
}
|
||||||
|
if &config.CanSendMediaMessages != nil {
|
||||||
|
v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages))
|
||||||
|
}
|
||||||
|
if &config.CanSendOtherMessages != nil {
|
||||||
|
v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages))
|
||||||
|
}
|
||||||
|
if &config.CanAddWebPagePreviews != nil {
|
||||||
|
v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews))
|
||||||
|
}
|
||||||
|
if config.UntilDate != 0 {
|
||||||
|
v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog("restrictChatMember", v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest("restrictChatMember", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PromoteChatMember add admin rights to user
|
||||||
|
func (bot *BotAPI) PromoteChatMember(config PromoteChatMemberConfig) (APIResponse, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
if config.SuperGroupUsername != "" {
|
||||||
|
v.Add("chat_id", config.SuperGroupUsername)
|
||||||
|
} else if config.ChannelUsername != "" {
|
||||||
|
v.Add("chat_id", config.ChannelUsername)
|
||||||
|
} else {
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
}
|
||||||
|
v.Add("user_id", strconv.Itoa(config.UserID))
|
||||||
|
|
||||||
|
if &config.CanChangeInfo != nil {
|
||||||
|
v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo))
|
||||||
|
}
|
||||||
|
if &config.CanPostMessages != nil {
|
||||||
|
v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages))
|
||||||
|
}
|
||||||
|
if &config.CanEditMessages != nil {
|
||||||
|
v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages))
|
||||||
|
}
|
||||||
|
if &config.CanDeleteMessages != nil {
|
||||||
|
v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages))
|
||||||
|
}
|
||||||
|
if &config.CanInviteUsers != nil {
|
||||||
|
v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers))
|
||||||
|
}
|
||||||
|
if &config.CanRestrictMembers != nil {
|
||||||
|
v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers))
|
||||||
|
}
|
||||||
|
if &config.CanPinMessages != nil {
|
||||||
|
v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages))
|
||||||
|
}
|
||||||
|
if &config.CanPromoteMembers != nil {
|
||||||
|
v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers))
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog("promoteChatMember", v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest("promoteChatMember", v)
|
||||||
|
}
|
||||||
|
|
||||||
// GetGameHighScores allows you to get the high scores for a game.
|
// GetGameHighScores allows you to get the high scores for a game.
|
||||||
func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHighScore, error) {
|
func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHighScore, error) {
|
||||||
v, _ := config.values()
|
v, _ := config.values()
|
||||||
@ -692,3 +805,96 @@ func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHigh
|
|||||||
|
|
||||||
return highScores, err
|
return highScores, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnswerShippingQuery allows you to reply to Update with shipping_query parameter.
|
||||||
|
func (bot *BotAPI) AnswerShippingQuery(config ShippingConfig) (APIResponse, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
v.Add("shipping_query_id", config.ShippingQueryID)
|
||||||
|
v.Add("ok", strconv.FormatBool(config.OK))
|
||||||
|
if config.OK == true {
|
||||||
|
data, err := json.Marshal(config.ShippingOptions)
|
||||||
|
if err != nil {
|
||||||
|
return APIResponse{}, err
|
||||||
|
}
|
||||||
|
v.Add("shipping_options", string(data))
|
||||||
|
} else {
|
||||||
|
v.Add("error_message", config.ErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog("answerShippingQuery", v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest("answerShippingQuery", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerPreCheckoutQuery allows you to reply to Update with pre_checkout_query.
|
||||||
|
func (bot *BotAPI) AnswerPreCheckoutQuery(config PreCheckoutConfig) (APIResponse, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
v.Add("pre_checkout_query_id", config.PreCheckoutQueryID)
|
||||||
|
v.Add("ok", strconv.FormatBool(config.OK))
|
||||||
|
if config.OK != true {
|
||||||
|
v.Add("error", config.ErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog("answerPreCheckoutQuery", v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest("answerPreCheckoutQuery", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMessage deletes a message in a chat
|
||||||
|
func (bot *BotAPI) DeleteMessage(config DeleteMessageConfig) (APIResponse, error) {
|
||||||
|
v, err := config.values()
|
||||||
|
if err != nil {
|
||||||
|
return APIResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog(config.method(), v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest(config.method(), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInviteLink get InviteLink for a chat
|
||||||
|
func (bot *BotAPI) GetInviteLink(config ChatConfig) (string, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
if config.SuperGroupUsername == "" {
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
} else {
|
||||||
|
v.Add("chat_id", config.SuperGroupUsername)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.MakeRequest("exportChatInviteLink", v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var inviteLink string
|
||||||
|
err = json.Unmarshal(resp.Result, &inviteLink)
|
||||||
|
|
||||||
|
return inviteLink, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PinChatMessage pin message in supergroup
|
||||||
|
func (bot *BotAPI) PinChatMessage(config PinChatMessageConfig) (APIResponse, error) {
|
||||||
|
v, err := config.values()
|
||||||
|
if err != nil {
|
||||||
|
return APIResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog(config.method(), v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest(config.method(), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnpinChatMessage unpin message in supergroup
|
||||||
|
func (bot *BotAPI) UnpinChatMessage(config UnpinChatMessageConfig) (APIResponse, error) {
|
||||||
|
v, err := config.values()
|
||||||
|
if err != nil {
|
||||||
|
return APIResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.debugLog(config.method(), v, nil)
|
||||||
|
|
||||||
|
return bot.MakeRequest(config.method(), v)
|
||||||
|
}
|
||||||
|
314
vendor/gopkg.in/telegram-bot-api.v4/configs.go
generated
vendored
314
vendor/gopkg.in/telegram-bot-api.v4/configs.go
generated
vendored
@ -198,7 +198,10 @@ type MessageConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of MessageConfig.
|
// values returns a url.Values representation of MessageConfig.
|
||||||
func (config MessageConfig) values() (url.Values, error) {
|
func (config MessageConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
v.Add("text", config.Text)
|
v.Add("text", config.Text)
|
||||||
v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
|
v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
|
||||||
if config.ParseMode != "" {
|
if config.ParseMode != "" {
|
||||||
@ -223,7 +226,10 @@ type ForwardConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of ForwardConfig.
|
// values returns a url.Values representation of ForwardConfig.
|
||||||
func (config ForwardConfig) values() (url.Values, error) {
|
func (config ForwardConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
|
v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
|
||||||
v.Add("message_id", strconv.Itoa(config.MessageID))
|
v.Add("message_id", strconv.Itoa(config.MessageID))
|
||||||
return v, nil
|
return v, nil
|
||||||
@ -253,7 +259,10 @@ func (config PhotoConfig) params() (map[string]string, error) {
|
|||||||
|
|
||||||
// Values returns a url.Values representation of PhotoConfig.
|
// Values returns a url.Values representation of PhotoConfig.
|
||||||
func (config PhotoConfig) values() (url.Values, error) {
|
func (config PhotoConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
if config.Caption != "" {
|
if config.Caption != "" {
|
||||||
@ -283,7 +292,10 @@ type AudioConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of AudioConfig.
|
// values returns a url.Values representation of AudioConfig.
|
||||||
func (config AudioConfig) values() (url.Values, error) {
|
func (config AudioConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
if config.Duration != 0 {
|
if config.Duration != 0 {
|
||||||
@ -337,13 +349,20 @@ func (config AudioConfig) method() string {
|
|||||||
// DocumentConfig contains information about a SendDocument request.
|
// DocumentConfig contains information about a SendDocument request.
|
||||||
type DocumentConfig struct {
|
type DocumentConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
|
Caption string
|
||||||
}
|
}
|
||||||
|
|
||||||
// values returns a url.Values representation of DocumentConfig.
|
// values returns a url.Values representation of DocumentConfig.
|
||||||
func (config DocumentConfig) values() (url.Values, error) {
|
func (config DocumentConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
|
if config.Caption != "" {
|
||||||
|
v.Add("caption", config.Caption)
|
||||||
|
}
|
||||||
|
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
@ -352,6 +371,10 @@ func (config DocumentConfig) values() (url.Values, error) {
|
|||||||
func (config DocumentConfig) params() (map[string]string, error) {
|
func (config DocumentConfig) params() (map[string]string, error) {
|
||||||
params, _ := config.BaseFile.params()
|
params, _ := config.BaseFile.params()
|
||||||
|
|
||||||
|
if config.Caption != "" {
|
||||||
|
params["caption"] = config.Caption
|
||||||
|
}
|
||||||
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +395,10 @@ type StickerConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of StickerConfig.
|
// values returns a url.Values representation of StickerConfig.
|
||||||
func (config StickerConfig) values() (url.Values, error) {
|
func (config StickerConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
|
|
||||||
@ -405,7 +431,10 @@ type VideoConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of VideoConfig.
|
// values returns a url.Values representation of VideoConfig.
|
||||||
func (config VideoConfig) values() (url.Values, error) {
|
func (config VideoConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
if config.Duration != 0 {
|
if config.Duration != 0 {
|
||||||
@ -422,6 +451,10 @@ func (config VideoConfig) values() (url.Values, error) {
|
|||||||
func (config VideoConfig) params() (map[string]string, error) {
|
func (config VideoConfig) params() (map[string]string, error) {
|
||||||
params, _ := config.BaseFile.params()
|
params, _ := config.BaseFile.params()
|
||||||
|
|
||||||
|
if config.Caption != "" {
|
||||||
|
params["caption"] = config.Caption
|
||||||
|
}
|
||||||
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,6 +468,57 @@ func (config VideoConfig) method() string {
|
|||||||
return "sendVideo"
|
return "sendVideo"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VideoNoteConfig contains information about a SendVideoNote request.
|
||||||
|
type VideoNoteConfig struct {
|
||||||
|
BaseFile
|
||||||
|
Duration int
|
||||||
|
Length int
|
||||||
|
}
|
||||||
|
|
||||||
|
// values returns a url.Values representation of VideoNoteConfig.
|
||||||
|
func (config VideoNoteConfig) values() (url.Values, error) {
|
||||||
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Add(config.name(), config.FileID)
|
||||||
|
if config.Duration != 0 {
|
||||||
|
v.Add("duration", strconv.Itoa(config.Duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Telegram API seems to have a bug, if no length is provided or it is 0, it will send an error response
|
||||||
|
if config.Length != 0 {
|
||||||
|
v.Add("length", strconv.Itoa(config.Length))
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// params returns a map[string]string representation of VideoNoteConfig.
|
||||||
|
func (config VideoNoteConfig) params() (map[string]string, error) {
|
||||||
|
params, _ := config.BaseFile.params()
|
||||||
|
|
||||||
|
if config.Length != 0 {
|
||||||
|
params["length"] = strconv.Itoa(config.Length)
|
||||||
|
}
|
||||||
|
if config.Duration != 0 {
|
||||||
|
params["duration"] = strconv.Itoa(config.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// name returns the field name for the VideoNote.
|
||||||
|
func (config VideoNoteConfig) name() string {
|
||||||
|
return "video_note"
|
||||||
|
}
|
||||||
|
|
||||||
|
// method returns Telegram API method name for sending VideoNote.
|
||||||
|
func (config VideoNoteConfig) method() string {
|
||||||
|
return "sendVideoNote"
|
||||||
|
}
|
||||||
|
|
||||||
// VoiceConfig contains information about a SendVoice request.
|
// VoiceConfig contains information about a SendVoice request.
|
||||||
type VoiceConfig struct {
|
type VoiceConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
@ -444,12 +528,18 @@ type VoiceConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of VoiceConfig.
|
// values returns a url.Values representation of VoiceConfig.
|
||||||
func (config VoiceConfig) values() (url.Values, error) {
|
func (config VoiceConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add(config.name(), config.FileID)
|
v.Add(config.name(), config.FileID)
|
||||||
if config.Duration != 0 {
|
if config.Duration != 0 {
|
||||||
v.Add("duration", strconv.Itoa(config.Duration))
|
v.Add("duration", strconv.Itoa(config.Duration))
|
||||||
}
|
}
|
||||||
|
if config.Caption != "" {
|
||||||
|
v.Add("caption", config.Caption)
|
||||||
|
}
|
||||||
|
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
@ -461,6 +551,9 @@ func (config VoiceConfig) params() (map[string]string, error) {
|
|||||||
if config.Duration != 0 {
|
if config.Duration != 0 {
|
||||||
params["duration"] = strconv.Itoa(config.Duration)
|
params["duration"] = strconv.Itoa(config.Duration)
|
||||||
}
|
}
|
||||||
|
if config.Caption != "" {
|
||||||
|
params["caption"] = config.Caption
|
||||||
|
}
|
||||||
|
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
@ -484,7 +577,10 @@ type LocationConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of LocationConfig.
|
// values returns a url.Values representation of LocationConfig.
|
||||||
func (config LocationConfig) values() (url.Values, error) {
|
func (config LocationConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
|
v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
|
||||||
v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
|
v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
|
||||||
@ -508,7 +604,10 @@ type VenueConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config VenueConfig) values() (url.Values, error) {
|
func (config VenueConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
|
v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
|
||||||
v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
|
v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
|
||||||
@ -534,7 +633,10 @@ type ContactConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config ContactConfig) values() (url.Values, error) {
|
func (config ContactConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add("phone_number", config.PhoneNumber)
|
v.Add("phone_number", config.PhoneNumber)
|
||||||
v.Add("first_name", config.FirstName)
|
v.Add("first_name", config.FirstName)
|
||||||
@ -554,7 +656,10 @@ type GameConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config GameConfig) values() (url.Values, error) {
|
func (config GameConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add("game_short_name", config.GameShortName)
|
v.Add("game_short_name", config.GameShortName)
|
||||||
|
|
||||||
@ -640,7 +745,10 @@ type ChatActionConfig struct {
|
|||||||
|
|
||||||
// values returns a url.Values representation of ChatActionConfig.
|
// values returns a url.Values representation of ChatActionConfig.
|
||||||
func (config ChatActionConfig) values() (url.Values, error) {
|
func (config ChatActionConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseChat.values()
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
v.Add("action", config.Action)
|
v.Add("action", config.Action)
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
@ -659,7 +767,10 @@ type EditMessageTextConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config EditMessageTextConfig) values() (url.Values, error) {
|
func (config EditMessageTextConfig) values() (url.Values, error) {
|
||||||
v, _ := config.BaseEdit.values()
|
v, err := config.BaseEdit.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
v.Add("text", config.Text)
|
v.Add("text", config.Text)
|
||||||
v.Add("parse_mode", config.ParseMode)
|
v.Add("parse_mode", config.ParseMode)
|
||||||
@ -728,6 +839,7 @@ type UpdateConfig struct {
|
|||||||
type WebhookConfig struct {
|
type WebhookConfig struct {
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
Certificate interface{}
|
Certificate interface{}
|
||||||
|
MaxConnections int
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileBytes contains information about a set of bytes to upload
|
// FileBytes contains information about a set of bytes to upload
|
||||||
@ -771,9 +883,39 @@ type CallbackConfig struct {
|
|||||||
type ChatMemberConfig struct {
|
type ChatMemberConfig struct {
|
||||||
ChatID int64
|
ChatID int64
|
||||||
SuperGroupUsername string
|
SuperGroupUsername string
|
||||||
|
ChannelUsername string
|
||||||
UserID int
|
UserID int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KickChatMemberConfig contains extra fields to kick user
|
||||||
|
type KickChatMemberConfig struct {
|
||||||
|
ChatMemberConfig
|
||||||
|
UntilDate int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestrictChatMemberConfig contains fields to restrict members of chat
|
||||||
|
type RestrictChatMemberConfig struct {
|
||||||
|
ChatMemberConfig
|
||||||
|
UntilDate int64
|
||||||
|
CanSendMessages *bool
|
||||||
|
CanSendMediaMessages *bool
|
||||||
|
CanSendOtherMessages *bool
|
||||||
|
CanAddWebPagePreviews *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
// ChatConfig contains information about getting information on a chat.
|
// ChatConfig contains information about getting information on a chat.
|
||||||
type ChatConfig struct {
|
type ChatConfig struct {
|
||||||
ChatID int64
|
ChatID int64
|
||||||
@ -787,3 +929,147 @@ type ChatConfigWithUser struct {
|
|||||||
SuperGroupUsername string
|
SuperGroupUsername string
|
||||||
UserID int
|
UserID int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
PhotoURL string
|
||||||
|
PhotoSize int
|
||||||
|
PhotoWidth int
|
||||||
|
PhotoHeight int
|
||||||
|
NeedName bool
|
||||||
|
NeedPhoneNumber bool
|
||||||
|
NeedEmail bool
|
||||||
|
NeedShippingAddress bool
|
||||||
|
IsFlexible bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config InvoiceConfig) values() (url.Values, error) {
|
||||||
|
v, err := config.BaseChat.values()
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
v.Add("title", config.Title)
|
||||||
|
v.Add("description", config.Description)
|
||||||
|
v.Add("payload", config.Payload)
|
||||||
|
v.Add("provider_token", config.ProviderToken)
|
||||||
|
v.Add("start_parameter", config.StartParameter)
|
||||||
|
v.Add("currency", config.Currency)
|
||||||
|
data, err := json.Marshal(config.Prices)
|
||||||
|
if err != nil {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
v.Add("prices", string(data))
|
||||||
|
if config.PhotoURL != "" {
|
||||||
|
v.Add("photo_url", config.PhotoURL)
|
||||||
|
}
|
||||||
|
if config.PhotoSize != 0 {
|
||||||
|
v.Add("photo_size", strconv.Itoa(config.PhotoSize))
|
||||||
|
}
|
||||||
|
if config.PhotoWidth != 0 {
|
||||||
|
v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
|
||||||
|
}
|
||||||
|
if config.PhotoHeight != 0 {
|
||||||
|
v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
|
||||||
|
}
|
||||||
|
if config.NeedName != false {
|
||||||
|
v.Add("need_name", strconv.FormatBool(config.NeedName))
|
||||||
|
}
|
||||||
|
if config.NeedPhoneNumber != false {
|
||||||
|
v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
|
||||||
|
}
|
||||||
|
if config.NeedEmail != false {
|
||||||
|
v.Add("need_email", strconv.FormatBool(config.NeedEmail))
|
||||||
|
}
|
||||||
|
if config.NeedShippingAddress != false {
|
||||||
|
v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
|
||||||
|
}
|
||||||
|
if config.IsFlexible != false {
|
||||||
|
v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, 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 {
|
||||||
|
ChatID int64
|
||||||
|
MessageID int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config DeleteMessageConfig) method() string {
|
||||||
|
return "deleteMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config DeleteMessageConfig) values() (url.Values, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
v.Add("message_id", strconv.Itoa(config.MessageID))
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PinChatMessageConfig contains information of a message in a chat to pin.
|
||||||
|
type PinChatMessageConfig struct {
|
||||||
|
ChatID int64
|
||||||
|
MessageID int
|
||||||
|
DisableNotification bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config PinChatMessageConfig) method() string {
|
||||||
|
return "pinChatMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config PinChatMessageConfig) values() (url.Values, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
v.Add("message_id", strconv.Itoa(config.MessageID))
|
||||||
|
v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnpinChatMessageConfig contains information of chat to unpin.
|
||||||
|
type UnpinChatMessageConfig struct {
|
||||||
|
ChatID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config UnpinChatMessageConfig) method() string {
|
||||||
|
return "unpinChatMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config UnpinChatMessageConfig) values() (url.Values, error) {
|
||||||
|
v := url.Values{}
|
||||||
|
|
||||||
|
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
44
vendor/gopkg.in/telegram-bot-api.v4/helpers.go
generated
vendored
44
vendor/gopkg.in/telegram-bot-api.v4/helpers.go
generated
vendored
@ -194,6 +194,37 @@ func NewVideoShare(chatID int64, fileID string) VideoConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewVideoNoteUpload creates a new video note uploader.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, file is a string path to the file,
|
||||||
|
// FileReader, or FileBytes.
|
||||||
|
func NewVideoNoteUpload(chatID int64, length int, file interface{}) VideoNoteConfig {
|
||||||
|
return VideoNoteConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
UseExisting: false,
|
||||||
|
},
|
||||||
|
Length: length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVideoNoteShare shares an existing video.
|
||||||
|
// You may use this to reshare an existing video without reuploading it.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, fileID is the ID of the video
|
||||||
|
// already uploaded.
|
||||||
|
func NewVideoNoteShare(chatID int64, length int, fileID string) VideoNoteConfig {
|
||||||
|
return VideoNoteConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
FileID: fileID,
|
||||||
|
UseExisting: true,
|
||||||
|
},
|
||||||
|
Length: length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewVoiceUpload creates a new voice uploader.
|
// NewVoiceUpload creates a new voice uploader.
|
||||||
//
|
//
|
||||||
// chatID is where to send it, file is a string path to the file,
|
// chatID is where to send it, file is a string path to the file,
|
||||||
@ -609,3 +640,16 @@ func NewCallbackWithAlert(id, text string) CallbackConfig {
|
|||||||
ShowAlert: true,
|
ShowAlert: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewInvoice created a new Invoice request to the user.
|
||||||
|
func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices *[]LabeledPrice) InvoiceConfig {
|
||||||
|
return InvoiceConfig{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
Title: title,
|
||||||
|
Description: description,
|
||||||
|
Payload: payload,
|
||||||
|
ProviderToken: providerToken,
|
||||||
|
StartParameter: startParameter,
|
||||||
|
Currency: currency,
|
||||||
|
Prices: prices}
|
||||||
|
}
|
||||||
|
178
vendor/gopkg.in/telegram-bot-api.v4/types.go
generated
vendored
178
vendor/gopkg.in/telegram-bot-api.v4/types.go
generated
vendored
@ -35,6 +35,18 @@ type Update struct {
|
|||||||
InlineQuery *InlineQuery `json:"inline_query"`
|
InlineQuery *InlineQuery `json:"inline_query"`
|
||||||
ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
|
ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
|
||||||
CallbackQuery *CallbackQuery `json:"callback_query"`
|
CallbackQuery *CallbackQuery `json:"callback_query"`
|
||||||
|
ShippingQuery *ShippingQuery `json:"shipping_query"`
|
||||||
|
PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatesChannel is the channel for getting updates.
|
||||||
|
type UpdatesChannel <-chan Update
|
||||||
|
|
||||||
|
// Clear discards all unprocessed incoming updates.
|
||||||
|
func (ch UpdatesChannel) Clear() {
|
||||||
|
for len(ch) != 0 {
|
||||||
|
<-ch
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// User is a user on Telegram.
|
// User is a user on Telegram.
|
||||||
@ -43,6 +55,8 @@ type User struct {
|
|||||||
FirstName string `json:"first_name"`
|
FirstName string `json:"first_name"`
|
||||||
LastName string `json:"last_name"` // optional
|
LastName string `json:"last_name"` // optional
|
||||||
UserName string `json:"username"` // optional
|
UserName string `json:"username"` // optional
|
||||||
|
LanguageCode string `json:"language_code"` // optional
|
||||||
|
IsBot bool `json:"is_bot"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// String displays a simple text version of a user.
|
// String displays a simple text version of a user.
|
||||||
@ -68,6 +82,12 @@ type GroupChat struct {
|
|||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChatPhoto represents a chat photo.
|
||||||
|
type ChatPhoto struct {
|
||||||
|
SmallFileID string `json:"small_file_id"`
|
||||||
|
BigFileID string `json:"big_file_id"`
|
||||||
|
}
|
||||||
|
|
||||||
// Chat contains information about the place a message was sent.
|
// Chat contains information about the place a message was sent.
|
||||||
type Chat struct {
|
type Chat struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
@ -77,6 +97,9 @@ type Chat struct {
|
|||||||
FirstName string `json:"first_name"` // optional
|
FirstName string `json:"first_name"` // optional
|
||||||
LastName string `json:"last_name"` // optional
|
LastName string `json:"last_name"` // optional
|
||||||
AllMembersAreAdmins bool `json:"all_members_are_administrators"` // optional
|
AllMembersAreAdmins bool `json:"all_members_are_administrators"` // optional
|
||||||
|
Photo *ChatPhoto `json:"photo"`
|
||||||
|
Description string `json:"description,omitempty"` // optional
|
||||||
|
InviteLink string `json:"invite_link,omitempty"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPrivate returns if the Chat is a private conversation.
|
// IsPrivate returns if the Chat is a private conversation.
|
||||||
@ -125,12 +148,13 @@ type Message struct {
|
|||||||
Photo *[]PhotoSize `json:"photo"` // optional
|
Photo *[]PhotoSize `json:"photo"` // optional
|
||||||
Sticker *Sticker `json:"sticker"` // optional
|
Sticker *Sticker `json:"sticker"` // optional
|
||||||
Video *Video `json:"video"` // optional
|
Video *Video `json:"video"` // optional
|
||||||
|
VideoNote *VideoNote `json:"video_note"` // optional
|
||||||
Voice *Voice `json:"voice"` // optional
|
Voice *Voice `json:"voice"` // optional
|
||||||
Caption string `json:"caption"` // optional
|
Caption string `json:"caption"` // optional
|
||||||
Contact *Contact `json:"contact"` // optional
|
Contact *Contact `json:"contact"` // optional
|
||||||
Location *Location `json:"location"` // optional
|
Location *Location `json:"location"` // optional
|
||||||
Venue *Venue `json:"venue"` // optional
|
Venue *Venue `json:"venue"` // optional
|
||||||
NewChatMember *User `json:"new_chat_member"` // optional
|
NewChatMembers *[]User `json:"new_chat_members"` // optional
|
||||||
LeftChatMember *User `json:"left_chat_member"` // optional
|
LeftChatMember *User `json:"left_chat_member"` // optional
|
||||||
NewChatTitle string `json:"new_chat_title"` // optional
|
NewChatTitle string `json:"new_chat_title"` // optional
|
||||||
NewChatPhoto *[]PhotoSize `json:"new_chat_photo"` // optional
|
NewChatPhoto *[]PhotoSize `json:"new_chat_photo"` // optional
|
||||||
@ -141,6 +165,8 @@ type Message struct {
|
|||||||
MigrateToChatID int64 `json:"migrate_to_chat_id"` // optional
|
MigrateToChatID int64 `json:"migrate_to_chat_id"` // optional
|
||||||
MigrateFromChatID int64 `json:"migrate_from_chat_id"` // optional
|
MigrateFromChatID int64 `json:"migrate_from_chat_id"` // optional
|
||||||
PinnedMessage *Message `json:"pinned_message"` // optional
|
PinnedMessage *Message `json:"pinned_message"` // optional
|
||||||
|
Invoice *Invoice `json:"invoice"` // optional
|
||||||
|
SuccessfulPayment *SuccessfulPayment `json:"successful_payment"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time converts the message timestamp into a Time.
|
// Time converts the message timestamp into a Time.
|
||||||
@ -148,21 +174,23 @@ func (m *Message) Time() time.Time {
|
|||||||
return time.Unix(int64(m.Date), 0)
|
return time.Unix(int64(m.Date), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsCommand returns true if message starts with '/'.
|
// IsCommand returns true if message starts with a "bot_command" entity.
|
||||||
func (m *Message) IsCommand() bool {
|
func (m *Message) IsCommand() bool {
|
||||||
return m.Text != "" && m.Text[0] == '/'
|
if m.Entities == nil || len(*m.Entities) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
entity := (*m.Entities)[0]
|
||||||
|
return entity.Offset == 0 && entity.Type == "bot_command"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command checks if the message was a command and if it was, returns the
|
// Command checks if the message was a command and if it was, returns the
|
||||||
// command. If the Message was not a command, it returns an empty string.
|
// command. If the Message was not a command, it returns an empty string.
|
||||||
//
|
//
|
||||||
// If the command contains the at bot syntax, it removes the bot name.
|
// If the command contains the at name syntax, it is removed. Use
|
||||||
|
// CommandWithAt() if you do not want that.
|
||||||
func (m *Message) Command() string {
|
func (m *Message) Command() string {
|
||||||
if !m.IsCommand() {
|
command := m.CommandWithAt()
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
command := strings.SplitN(m.Text, " ", 2)[0][1:]
|
|
||||||
|
|
||||||
if i := strings.Index(command, "@"); i != -1 {
|
if i := strings.Index(command, "@"); i != -1 {
|
||||||
command = command[:i]
|
command = command[:i]
|
||||||
@ -171,20 +199,42 @@ func (m *Message) Command() string {
|
|||||||
return command
|
return command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommandWithAt checks if the message was a command and if it was, returns the
|
||||||
|
// command. If the Message was not a command, it returns an empty string.
|
||||||
|
//
|
||||||
|
// If the command contains the at name syntax, it is not removed. Use Command()
|
||||||
|
// if you want that.
|
||||||
|
func (m *Message) CommandWithAt() string {
|
||||||
|
if !m.IsCommand() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCommand() checks that the message begins with a bot_command entity
|
||||||
|
entity := (*m.Entities)[0]
|
||||||
|
return m.Text[1:entity.Length]
|
||||||
|
}
|
||||||
|
|
||||||
// CommandArguments checks if the message was a command and if it was,
|
// CommandArguments checks if the message was a command and if it was,
|
||||||
// returns all text after the command name. If the Message was not a
|
// returns all text after the command name. If the Message was not a
|
||||||
// command, it returns an empty string.
|
// command, it returns an empty string.
|
||||||
|
//
|
||||||
|
// Note: The first character after the command name is omitted:
|
||||||
|
// - "/foo bar baz" yields "bar baz", not " bar baz"
|
||||||
|
// - "/foo-bar baz" yields "bar baz", too
|
||||||
|
// Even though the latter is not a command conforming to the spec, the API
|
||||||
|
// marks "/foo" as command entity.
|
||||||
func (m *Message) CommandArguments() string {
|
func (m *Message) CommandArguments() string {
|
||||||
if !m.IsCommand() {
|
if !m.IsCommand() {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
split := strings.SplitN(m.Text, " ", 2)
|
// IsCommand() checks that the message begins with a bot_command entity
|
||||||
if len(split) != 2 {
|
entity := (*m.Entities)[0]
|
||||||
return ""
|
if len(m.Text) == entity.Length {
|
||||||
|
return "" // The command makes up the whole message
|
||||||
|
} else {
|
||||||
|
return m.Text[entity.Length+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.SplitN(m.Text, " ", 2)[1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageEntity contains information about data in a Message.
|
// MessageEntity contains information about data in a Message.
|
||||||
@ -253,6 +303,15 @@ type Video struct {
|
|||||||
FileSize int `json:"file_size"` // optional
|
FileSize int `json:"file_size"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VideoNote contains information about a video.
|
||||||
|
type VideoNote struct {
|
||||||
|
FileID string `json:"file_id"`
|
||||||
|
Length int `json:"length"`
|
||||||
|
Duration int `json:"duration"`
|
||||||
|
Thumbnail *PhotoSize `json:"thumb"` // optional
|
||||||
|
FileSize int `json:"file_size"` // optional
|
||||||
|
}
|
||||||
|
|
||||||
// Voice contains information about a voice.
|
// Voice contains information about a voice.
|
||||||
type Voice struct {
|
type Voice struct {
|
||||||
FileID string `json:"file_id"`
|
FileID string `json:"file_id"`
|
||||||
@ -349,8 +408,9 @@ type InlineKeyboardButton struct {
|
|||||||
URL *string `json:"url,omitempty"` // optional
|
URL *string `json:"url,omitempty"` // optional
|
||||||
CallbackData *string `json:"callback_data,omitempty"` // optional
|
CallbackData *string `json:"callback_data,omitempty"` // optional
|
||||||
SwitchInlineQuery *string `json:"switch_inline_query,omitempty"` // optional
|
SwitchInlineQuery *string `json:"switch_inline_query,omitempty"` // optional
|
||||||
SwitchInlineQueryCurrentChat *string `json:"switch_inline_query_current_chat"` // optional
|
SwitchInlineQueryCurrentChat *string `json:"switch_inline_query_current_chat,omitempty"` // optional
|
||||||
CallbackGame *CallbackGame `json:"callback_game"` // optional
|
CallbackGame *CallbackGame `json:"callback_game,omitempty"` // optional
|
||||||
|
Pay bool `json:"pay,omitempty"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallbackQuery is data sent when a keyboard button with callback data
|
// CallbackQuery is data sent when a keyboard button with callback data
|
||||||
@ -376,6 +436,20 @@ type ForceReply struct {
|
|||||||
type ChatMember struct {
|
type ChatMember struct {
|
||||||
User *User `json:"user"`
|
User *User `json:"user"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
|
UntilDate int64 `json:"until_date,omitempty"` // optional
|
||||||
|
CanBeEdited bool `json:"can_be_edited,omitempty"` // optional
|
||||||
|
CanChangeInfo bool `json:"can_change_info,omitempty"` // optional
|
||||||
|
CanPostMessages bool `json:"can_post_messages,omitempty"` // optional
|
||||||
|
CanEditMessages bool `json:"can_edit_messages,omitempty"` // optional
|
||||||
|
CanDeleteMessages bool `json:"can_delete_messages,omitempty"` // optional
|
||||||
|
CanInviteUsers bool `json:"can_invite_users,omitempty"` // optional
|
||||||
|
CanRestrictMembers bool `json:"can_restrict_members,omitempty"` // optional
|
||||||
|
CanPinMessages bool `json:"can_pin_messages,omitempty"` // optional
|
||||||
|
CanPromoteMembers bool `json:"can_promote_members,omitempty"` // optional
|
||||||
|
CanSendMessages bool `json:"can_send_messages,omitempty"` // optional
|
||||||
|
CanSendMediaMessages bool `json:"can_send_media_messages,omitempty"` // optional
|
||||||
|
CanSendOtherMessages bool `json:"can_send_other_messages,omitempty"` // optional
|
||||||
|
CanAddWebPagePreviews bool `json:"can_add_web_page_previews,omitempty"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsCreator returns if the ChatMember was the creator of the chat.
|
// IsCreator returns if the ChatMember was the creator of the chat.
|
||||||
@ -483,6 +557,7 @@ type InlineQueryResultGIF struct {
|
|||||||
URL string `json:"gif_url"` // required
|
URL string `json:"gif_url"` // required
|
||||||
Width int `json:"gif_width"`
|
Width int `json:"gif_width"`
|
||||||
Height int `json:"gif_height"`
|
Height int `json:"gif_height"`
|
||||||
|
Duration int `json:"gif_duration"`
|
||||||
ThumbURL string `json:"thumb_url"`
|
ThumbURL string `json:"thumb_url"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Caption string `json:"caption"`
|
Caption string `json:"caption"`
|
||||||
@ -497,6 +572,7 @@ type InlineQueryResultMPEG4GIF struct {
|
|||||||
URL string `json:"mpeg4_url"` // required
|
URL string `json:"mpeg4_url"` // required
|
||||||
Width int `json:"mpeg4_width"`
|
Width int `json:"mpeg4_width"`
|
||||||
Height int `json:"mpeg4_height"`
|
Height int `json:"mpeg4_height"`
|
||||||
|
Duration int `json:"mpeg4_duration"`
|
||||||
ThumbURL string `json:"thumb_url"`
|
ThumbURL string `json:"thumb_url"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Caption string `json:"caption"`
|
Caption string `json:"caption"`
|
||||||
@ -625,3 +701,73 @@ type InputContactMessageContent struct {
|
|||||||
FirstName string `json:"first_name"`
|
FirstName string `json:"first_name"`
|
||||||
LastName string `json:"last_name"`
|
LastName string `json:"last_name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoice contains basic information about an invoice.
|
||||||
|
type Invoice struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
StartParameter string `json:"start_parameter"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
TotalAmount int `json:"total_amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabeledPrice represents a portion of the price for goods or services.
|
||||||
|
type LabeledPrice struct {
|
||||||
|
Label string `json:"label"`
|
||||||
|
Amount int `json:"amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShippingAddress represents a shipping address.
|
||||||
|
type ShippingAddress struct {
|
||||||
|
CountryCode string `json:"country_code"`
|
||||||
|
State string `json:"state"`
|
||||||
|
City string `json:"city"`
|
||||||
|
StreetLine1 string `json:"street_line1"`
|
||||||
|
StreetLine2 string `json:"street_line2"`
|
||||||
|
PostCode string `json:"post_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderInfo represents information about an order.
|
||||||
|
type OrderInfo struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
PhoneNumber string `json:"phone_number,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShippingOption represents one shipping option.
|
||||||
|
type ShippingOption struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Prices *[]LabeledPrice `json:"prices"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SuccessfulPayment contains basic information about a successful payment.
|
||||||
|
type SuccessfulPayment struct {
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
TotalAmount int `json:"total_amount"`
|
||||||
|
InvoicePayload string `json:"invoice_payload"`
|
||||||
|
ShippingOptionID string `json:"shipping_option_id,omitempty"`
|
||||||
|
OrderInfo *OrderInfo `json:"order_info,omitempty"`
|
||||||
|
TelegramPaymentChargeID string `json:"telegram_payment_charge_id"`
|
||||||
|
ProviderPaymentChargeID string `json:"provider_payment_charge_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShippingQuery contains information about an incoming shipping query.
|
||||||
|
type ShippingQuery struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
From *User `json:"from"`
|
||||||
|
InvoicePayload string `json:"invoice_payload"`
|
||||||
|
ShippingAddress *ShippingAddress `json:"shipping_address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreCheckoutQuery contains information about an incoming pre-checkout query.
|
||||||
|
type PreCheckoutQuery struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
From *User `json:"from"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
TotalAmount int `json:"total_amount"`
|
||||||
|
InvoicePayload string `json:"invoice_payload"`
|
||||||
|
ShippingOptionID string `json:"shipping_option_id,omitempty"`
|
||||||
|
OrderInfo *OrderInfo `json:"order_info,omitempty"`
|
||||||
|
}
|
||||||
|
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@ -75,10 +75,10 @@
|
|||||||
"revisionTime": "2017-06-25T03:28:08Z"
|
"revisionTime": "2017-06-25T03:28:08Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "AzeP9gpBdHRcPQ5ozBpkBcqfInk=",
|
"checksumSHA1": "JaRjqSc0lOpA0V7avHWBex1IY+w=",
|
||||||
"path": "gopkg.in/telegram-bot-api.v4",
|
"path": "gopkg.in/telegram-bot-api.v4",
|
||||||
"revision": "0a57807db79efce7f6719fbb2c0e0f83fda79aec",
|
"revision": "2022d04b94f50056a09962b1ac81cdd821d20a55",
|
||||||
"revisionTime": "2016-11-25T05:50:35Z"
|
"revisionTime": "2017-11-09T18:51:50Z"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rootPath": "github.com/appleboy/drone-telegram"
|
"rootPath": "github.com/appleboy/drone-telegram"
|
||||||
|
Loading…
Reference in New Issue
Block a user