github.com/alexis81/domosgo@v0.0.0-20191016125037-5aee90a434af/Domos/src/gopkg.in/telegram-bot-api.v4/bot.go (about) 1 // Package tgbotapi has functions and types used for interacting with 2 // the Telegram Bot API. 3 package tgbotapi 4 5 import ( 6 "bytes" 7 "encoding/json" 8 "errors" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "log" 13 "net/http" 14 "net/url" 15 "os" 16 "strconv" 17 "strings" 18 "time" 19 20 "github.com/technoweenie/multipartstreamer" 21 ) 22 23 // BotAPI allows you to interact with the Telegram Bot API. 24 type BotAPI struct { 25 Token string `json:"token"` 26 Debug bool `json:"debug"` 27 Buffer int `json:"buffer"` 28 29 Self User `json:"-"` 30 Client *http.Client `json:"-"` 31 } 32 33 // NewBotAPI creates a new BotAPI instance. 34 // 35 // It requires a token, provided by @BotFather on Telegram. 36 func NewBotAPI(token string) (*BotAPI, error) { 37 return NewBotAPIWithClient(token, &http.Client{}) 38 } 39 40 // NewBotAPIWithClient creates a new BotAPI instance 41 // and allows you to pass a http.Client. 42 // 43 // It requires a token, provided by @BotFather on Telegram. 44 func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { 45 bot := &BotAPI{ 46 Token: token, 47 Client: client, 48 Buffer: 100, 49 } 50 51 self, err := bot.GetMe() 52 if err != nil { 53 return nil, err 54 } 55 56 bot.Self = self 57 58 return bot, nil 59 } 60 61 // MakeRequest makes a request to a specific endpoint with our token. 62 func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, error) { 63 method := fmt.Sprintf(APIEndpoint, bot.Token, endpoint) 64 65 resp, err := bot.Client.PostForm(method, params) 66 if err != nil { 67 return APIResponse{}, err 68 } 69 defer resp.Body.Close() 70 71 var apiResp APIResponse 72 bytes, err := bot.decodeAPIResponse(resp.Body, &apiResp) 73 if err != nil { 74 return apiResp, err 75 } 76 77 if bot.Debug { 78 log.Printf("%s resp: %s", endpoint, bytes) 79 } 80 81 if !apiResp.Ok { 82 parameters := ResponseParameters{} 83 if apiResp.Parameters != nil { 84 parameters = *apiResp.Parameters 85 } 86 return apiResp, Error{apiResp.Description, parameters} 87 } 88 89 return apiResp, nil 90 } 91 92 // decodeAPIResponse decode response and return slice of bytes if debug enabled. 93 // If debug disabled, just decode http.Response.Body stream to APIResponse struct 94 // for efficient memory usage 95 func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse) (_ []byte, err error) { 96 if !bot.Debug { 97 dec := json.NewDecoder(responseBody) 98 err = dec.Decode(resp) 99 return 100 } 101 102 // if debug, read reponse body 103 data, err := ioutil.ReadAll(responseBody) 104 if err != nil { 105 return 106 } 107 108 err = json.Unmarshal(data, resp) 109 if err != nil { 110 return 111 } 112 113 return data, nil 114 } 115 116 // makeMessageRequest makes a request to a method that returns a Message. 117 func (bot *BotAPI) makeMessageRequest(endpoint string, params url.Values) (Message, error) { 118 resp, err := bot.MakeRequest(endpoint, params) 119 if err != nil { 120 return Message{}, err 121 } 122 123 var message Message 124 json.Unmarshal(resp.Result, &message) 125 126 bot.debugLog(endpoint, params, message) 127 128 return message, nil 129 } 130 131 // UploadFile makes a request to the API with a file. 132 // 133 // Requires the parameter to hold the file not be in the params. 134 // File should be a string to a file path, a FileBytes struct, 135 // a FileReader struct, or a url.URL. 136 // 137 // Note that if your FileReader has a size set to -1, it will read 138 // the file into memory to calculate a size. 139 func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldname string, file interface{}) (APIResponse, error) { 140 ms := multipartstreamer.New() 141 142 switch f := file.(type) { 143 case string: 144 ms.WriteFields(params) 145 146 fileHandle, err := os.Open(f) 147 if err != nil { 148 return APIResponse{}, err 149 } 150 defer fileHandle.Close() 151 152 fi, err := os.Stat(f) 153 if err != nil { 154 return APIResponse{}, err 155 } 156 157 ms.WriteReader(fieldname, fileHandle.Name(), fi.Size(), fileHandle) 158 case FileBytes: 159 ms.WriteFields(params) 160 161 buf := bytes.NewBuffer(f.Bytes) 162 ms.WriteReader(fieldname, f.Name, int64(len(f.Bytes)), buf) 163 case FileReader: 164 ms.WriteFields(params) 165 166 if f.Size != -1 { 167 ms.WriteReader(fieldname, f.Name, f.Size, f.Reader) 168 169 break 170 } 171 172 data, err := ioutil.ReadAll(f.Reader) 173 if err != nil { 174 return APIResponse{}, err 175 } 176 177 buf := bytes.NewBuffer(data) 178 179 ms.WriteReader(fieldname, f.Name, int64(len(data)), buf) 180 case url.URL: 181 params[fieldname] = f.String() 182 183 ms.WriteFields(params) 184 default: 185 return APIResponse{}, errors.New(ErrBadFileType) 186 } 187 188 method := fmt.Sprintf(APIEndpoint, bot.Token, endpoint) 189 190 req, err := http.NewRequest("POST", method, nil) 191 if err != nil { 192 return APIResponse{}, err 193 } 194 195 ms.SetupRequest(req) 196 197 res, err := bot.Client.Do(req) 198 if err != nil { 199 return APIResponse{}, err 200 } 201 defer res.Body.Close() 202 203 bytes, err := ioutil.ReadAll(res.Body) 204 if err != nil { 205 return APIResponse{}, err 206 } 207 208 if bot.Debug { 209 log.Println(string(bytes)) 210 } 211 212 var apiResp APIResponse 213 214 err = json.Unmarshal(bytes, &apiResp) 215 if err != nil { 216 return APIResponse{}, err 217 } 218 219 if !apiResp.Ok { 220 return APIResponse{}, errors.New(apiResp.Description) 221 } 222 223 return apiResp, nil 224 } 225 226 // GetFileDirectURL returns direct URL to file 227 // 228 // It requires the FileID. 229 func (bot *BotAPI) GetFileDirectURL(fileID string) (string, error) { 230 file, err := bot.GetFile(FileConfig{fileID}) 231 232 if err != nil { 233 return "", err 234 } 235 236 return file.Link(bot.Token), nil 237 } 238 239 // GetMe fetches the currently authenticated bot. 240 // 241 // This method is called upon creation to validate the token, 242 // and so you may get this data from BotAPI.Self without the need for 243 // another request. 244 func (bot *BotAPI) GetMe() (User, error) { 245 resp, err := bot.MakeRequest("getMe", nil) 246 if err != nil { 247 return User{}, err 248 } 249 250 var user User 251 json.Unmarshal(resp.Result, &user) 252 253 bot.debugLog("getMe", nil, user) 254 255 return user, nil 256 } 257 258 // IsMessageToMe returns true if message directed to this bot. 259 // 260 // It requires the Message. 261 func (bot *BotAPI) IsMessageToMe(message Message) bool { 262 return strings.Contains(message.Text, "@"+bot.Self.UserName) 263 } 264 265 // Send will send a Chattable item to Telegram. 266 // 267 // It requires the Chattable to send. 268 func (bot *BotAPI) Send(c Chattable) (Message, error) { 269 switch c.(type) { 270 case Fileable: 271 return bot.sendFile(c.(Fileable)) 272 default: 273 return bot.sendChattable(c) 274 } 275 } 276 277 // debugLog checks if the bot is currently running in debug mode, and if 278 // so will display information about the request and response in the 279 // debug log. 280 func (bot *BotAPI) debugLog(context string, v url.Values, message interface{}) { 281 if bot.Debug { 282 log.Printf("%s req : %+v\n", context, v) 283 log.Printf("%s resp: %+v\n", context, message) 284 } 285 } 286 287 // sendExisting will send a Message with an existing file to Telegram. 288 func (bot *BotAPI) sendExisting(method string, config Fileable) (Message, error) { 289 v, err := config.values() 290 291 if err != nil { 292 return Message{}, err 293 } 294 295 message, err := bot.makeMessageRequest(method, v) 296 if err != nil { 297 return Message{}, err 298 } 299 300 return message, nil 301 } 302 303 // uploadAndSend will send a Message with a new file to Telegram. 304 func (bot *BotAPI) uploadAndSend(method string, config Fileable) (Message, error) { 305 params, err := config.params() 306 if err != nil { 307 return Message{}, err 308 } 309 310 file := config.getFile() 311 312 resp, err := bot.UploadFile(method, params, config.name(), file) 313 if err != nil { 314 return Message{}, err 315 } 316 317 var message Message 318 json.Unmarshal(resp.Result, &message) 319 320 bot.debugLog(method, nil, message) 321 322 return message, nil 323 } 324 325 // sendFile determines if the file is using an existing file or uploading 326 // a new file, then sends it as needed. 327 func (bot *BotAPI) sendFile(config Fileable) (Message, error) { 328 if config.useExistingFile() { 329 return bot.sendExisting(config.method(), config) 330 } 331 332 return bot.uploadAndSend(config.method(), config) 333 } 334 335 // sendChattable sends a Chattable. 336 func (bot *BotAPI) sendChattable(config Chattable) (Message, error) { 337 v, err := config.values() 338 if err != nil { 339 return Message{}, err 340 } 341 342 message, err := bot.makeMessageRequest(config.method(), v) 343 344 if err != nil { 345 return Message{}, err 346 } 347 348 return message, nil 349 } 350 351 // GetUserProfilePhotos gets a user's profile photos. 352 // 353 // It requires UserID. 354 // Offset and Limit are optional. 355 func (bot *BotAPI) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) { 356 v := url.Values{} 357 v.Add("user_id", strconv.Itoa(config.UserID)) 358 if config.Offset != 0 { 359 v.Add("offset", strconv.Itoa(config.Offset)) 360 } 361 if config.Limit != 0 { 362 v.Add("limit", strconv.Itoa(config.Limit)) 363 } 364 365 resp, err := bot.MakeRequest("getUserProfilePhotos", v) 366 if err != nil { 367 return UserProfilePhotos{}, err 368 } 369 370 var profilePhotos UserProfilePhotos 371 json.Unmarshal(resp.Result, &profilePhotos) 372 373 bot.debugLog("GetUserProfilePhoto", v, profilePhotos) 374 375 return profilePhotos, nil 376 } 377 378 // GetFile returns a File which can download a file from Telegram. 379 // 380 // Requires FileID. 381 func (bot *BotAPI) GetFile(config FileConfig) (File, error) { 382 v := url.Values{} 383 v.Add("file_id", config.FileID) 384 385 resp, err := bot.MakeRequest("getFile", v) 386 if err != nil { 387 return File{}, err 388 } 389 390 var file File 391 json.Unmarshal(resp.Result, &file) 392 393 bot.debugLog("GetFile", v, file) 394 395 return file, nil 396 } 397 398 // GetUpdates fetches updates. 399 // If a WebHook is set, this will not return any data! 400 // 401 // Offset, Limit, and Timeout are optional. 402 // To avoid stale items, set Offset to one higher than the previous item. 403 // Set Timeout to a large number to reduce requests so you can get updates 404 // instantly instead of having to wait between requests. 405 func (bot *BotAPI) GetUpdates(config UpdateConfig) ([]Update, error) { 406 v := url.Values{} 407 if config.Offset != 0 { 408 v.Add("offset", strconv.Itoa(config.Offset)) 409 } 410 if config.Limit > 0 { 411 v.Add("limit", strconv.Itoa(config.Limit)) 412 } 413 if config.Timeout > 0 { 414 v.Add("timeout", strconv.Itoa(config.Timeout)) 415 } 416 417 resp, err := bot.MakeRequest("getUpdates", v) 418 if err != nil { 419 return []Update{}, err 420 } 421 422 var updates []Update 423 json.Unmarshal(resp.Result, &updates) 424 425 bot.debugLog("getUpdates", v, updates) 426 427 return updates, nil 428 } 429 430 // RemoveWebhook unsets the webhook. 431 func (bot *BotAPI) RemoveWebhook() (APIResponse, error) { 432 return bot.MakeRequest("setWebhook", url.Values{}) 433 } 434 435 // SetWebhook sets a webhook. 436 // 437 // If this is set, GetUpdates will not get any data! 438 // 439 // If you do not have a legitimate TLS certificate, you need to include 440 // your self signed certificate with the config. 441 func (bot *BotAPI) SetWebhook(config WebhookConfig) (APIResponse, error) { 442 443 if config.Certificate == nil { 444 v := url.Values{} 445 v.Add("url", config.URL.String()) 446 if config.MaxConnections != 0 { 447 v.Add("max_connections", strconv.Itoa(config.MaxConnections)) 448 } 449 450 return bot.MakeRequest("setWebhook", v) 451 } 452 453 params := make(map[string]string) 454 params["url"] = config.URL.String() 455 if config.MaxConnections != 0 { 456 params["max_connections"] = strconv.Itoa(config.MaxConnections) 457 } 458 459 resp, err := bot.UploadFile("setWebhook", params, "certificate", config.Certificate) 460 if err != nil { 461 return APIResponse{}, err 462 } 463 464 return resp, nil 465 } 466 467 // GetWebhookInfo allows you to fetch information about a webhook and if 468 // one currently is set, along with pending update count and error messages. 469 func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) { 470 resp, err := bot.MakeRequest("getWebhookInfo", url.Values{}) 471 if err != nil { 472 return WebhookInfo{}, err 473 } 474 475 var info WebhookInfo 476 err = json.Unmarshal(resp.Result, &info) 477 478 return info, err 479 } 480 481 // GetUpdatesChan starts and returns a channel for getting updates. 482 func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) { 483 ch := make(chan Update, bot.Buffer) 484 485 go func() { 486 for { 487 updates, err := bot.GetUpdates(config) 488 if err != nil { 489 log.Println(err) 490 log.Println("Failed to get updates, retrying in 3 seconds...") 491 time.Sleep(time.Second * 3) 492 493 continue 494 } 495 496 for _, update := range updates { 497 if update.UpdateID >= config.Offset { 498 config.Offset = update.UpdateID + 1 499 ch <- update 500 } 501 } 502 } 503 }() 504 505 return ch, nil 506 } 507 508 // ListenForWebhook registers a http handler for a webhook. 509 func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel { 510 ch := make(chan Update, bot.Buffer) 511 512 http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 513 bytes, _ := ioutil.ReadAll(r.Body) 514 515 var update Update 516 json.Unmarshal(bytes, &update) 517 518 ch <- update 519 }) 520 521 return ch 522 } 523 524 // AnswerInlineQuery sends a response to an inline query. 525 // 526 // Note that you must respond to an inline query within 30 seconds. 527 func (bot *BotAPI) AnswerInlineQuery(config InlineConfig) (APIResponse, error) { 528 v := url.Values{} 529 530 v.Add("inline_query_id", config.InlineQueryID) 531 v.Add("cache_time", strconv.Itoa(config.CacheTime)) 532 v.Add("is_personal", strconv.FormatBool(config.IsPersonal)) 533 v.Add("next_offset", config.NextOffset) 534 data, err := json.Marshal(config.Results) 535 if err != nil { 536 return APIResponse{}, err 537 } 538 v.Add("results", string(data)) 539 v.Add("switch_pm_text", config.SwitchPMText) 540 v.Add("switch_pm_parameter", config.SwitchPMParameter) 541 542 bot.debugLog("answerInlineQuery", v, nil) 543 544 return bot.MakeRequest("answerInlineQuery", v) 545 } 546 547 // AnswerCallbackQuery sends a response to an inline query callback. 548 func (bot *BotAPI) AnswerCallbackQuery(config CallbackConfig) (APIResponse, error) { 549 v := url.Values{} 550 551 v.Add("callback_query_id", config.CallbackQueryID) 552 if config.Text != "" { 553 v.Add("text", config.Text) 554 } 555 v.Add("show_alert", strconv.FormatBool(config.ShowAlert)) 556 if config.URL != "" { 557 v.Add("url", config.URL) 558 } 559 v.Add("cache_time", strconv.Itoa(config.CacheTime)) 560 561 bot.debugLog("answerCallbackQuery", v, nil) 562 563 return bot.MakeRequest("answerCallbackQuery", v) 564 } 565 566 // KickChatMember kicks a user from a chat. Note that this only will work 567 // in supergroups, and requires the bot to be an admin. Also note they 568 // will be unable to rejoin until they are unbanned. 569 func (bot *BotAPI) KickChatMember(config KickChatMemberConfig) (APIResponse, error) { 570 v := url.Values{} 571 572 if config.SuperGroupUsername == "" { 573 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 574 } else { 575 v.Add("chat_id", config.SuperGroupUsername) 576 } 577 v.Add("user_id", strconv.Itoa(config.UserID)) 578 579 if config.UntilDate != 0 { 580 v.Add("until_date", strconv.FormatInt(config.UntilDate, 10)) 581 } 582 583 bot.debugLog("kickChatMember", v, nil) 584 585 return bot.MakeRequest("kickChatMember", v) 586 } 587 588 // LeaveChat makes the bot leave the chat. 589 func (bot *BotAPI) LeaveChat(config ChatConfig) (APIResponse, error) { 590 v := url.Values{} 591 592 if config.SuperGroupUsername == "" { 593 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 594 } else { 595 v.Add("chat_id", config.SuperGroupUsername) 596 } 597 598 bot.debugLog("leaveChat", v, nil) 599 600 return bot.MakeRequest("leaveChat", v) 601 } 602 603 // GetChat gets information about a chat. 604 func (bot *BotAPI) GetChat(config ChatConfig) (Chat, error) { 605 v := url.Values{} 606 607 if config.SuperGroupUsername == "" { 608 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 609 } else { 610 v.Add("chat_id", config.SuperGroupUsername) 611 } 612 613 resp, err := bot.MakeRequest("getChat", v) 614 if err != nil { 615 return Chat{}, err 616 } 617 618 var chat Chat 619 err = json.Unmarshal(resp.Result, &chat) 620 621 bot.debugLog("getChat", v, chat) 622 623 return chat, err 624 } 625 626 // GetChatAdministrators gets a list of administrators in the chat. 627 // 628 // If none have been appointed, only the creator will be returned. 629 // Bots are not shown, even if they are an administrator. 630 func (bot *BotAPI) GetChatAdministrators(config ChatConfig) ([]ChatMember, error) { 631 v := url.Values{} 632 633 if config.SuperGroupUsername == "" { 634 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 635 } else { 636 v.Add("chat_id", config.SuperGroupUsername) 637 } 638 639 resp, err := bot.MakeRequest("getChatAdministrators", v) 640 if err != nil { 641 return []ChatMember{}, err 642 } 643 644 var members []ChatMember 645 err = json.Unmarshal(resp.Result, &members) 646 647 bot.debugLog("getChatAdministrators", v, members) 648 649 return members, err 650 } 651 652 // GetChatMembersCount gets the number of users in a chat. 653 func (bot *BotAPI) GetChatMembersCount(config ChatConfig) (int, error) { 654 v := url.Values{} 655 656 if config.SuperGroupUsername == "" { 657 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 658 } else { 659 v.Add("chat_id", config.SuperGroupUsername) 660 } 661 662 resp, err := bot.MakeRequest("getChatMembersCount", v) 663 if err != nil { 664 return -1, err 665 } 666 667 var count int 668 err = json.Unmarshal(resp.Result, &count) 669 670 bot.debugLog("getChatMembersCount", v, count) 671 672 return count, err 673 } 674 675 // GetChatMember gets a specific chat member. 676 func (bot *BotAPI) GetChatMember(config ChatConfigWithUser) (ChatMember, error) { 677 v := url.Values{} 678 679 if config.SuperGroupUsername == "" { 680 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 681 } else { 682 v.Add("chat_id", config.SuperGroupUsername) 683 } 684 v.Add("user_id", strconv.Itoa(config.UserID)) 685 686 resp, err := bot.MakeRequest("getChatMember", v) 687 if err != nil { 688 return ChatMember{}, err 689 } 690 691 var member ChatMember 692 err = json.Unmarshal(resp.Result, &member) 693 694 bot.debugLog("getChatMember", v, member) 695 696 return member, err 697 } 698 699 // UnbanChatMember unbans a user from a chat. Note that this only will work 700 // in supergroups and channels, and requires the bot to be an admin. 701 func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error) { 702 v := url.Values{} 703 704 if config.SuperGroupUsername != "" { 705 v.Add("chat_id", config.SuperGroupUsername) 706 } else if config.ChannelUsername != "" { 707 v.Add("chat_id", config.ChannelUsername) 708 } else { 709 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 710 } 711 v.Add("user_id", strconv.Itoa(config.UserID)) 712 713 bot.debugLog("unbanChatMember", v, nil) 714 715 return bot.MakeRequest("unbanChatMember", v) 716 } 717 718 // RestrictChatMember to restrict a user in a supergroup. The bot must be an 719 //administrator in the supergroup for this to work and must have the 720 //appropriate admin rights. Pass True for all boolean parameters to lift 721 //restrictions from a user. Returns True on success. 722 func (bot *BotAPI) RestrictChatMember(config RestrictChatMemberConfig) (APIResponse, error) { 723 v := url.Values{} 724 725 if config.SuperGroupUsername != "" { 726 v.Add("chat_id", config.SuperGroupUsername) 727 } else if config.ChannelUsername != "" { 728 v.Add("chat_id", config.ChannelUsername) 729 } else { 730 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 731 } 732 v.Add("user_id", strconv.Itoa(config.UserID)) 733 734 if config.CanSendMessages != nil { 735 v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages)) 736 } 737 if config.CanSendMediaMessages != nil { 738 v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages)) 739 } 740 if config.CanSendOtherMessages != nil { 741 v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages)) 742 } 743 if config.CanAddWebPagePreviews != nil { 744 v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews)) 745 } 746 if config.UntilDate != 0 { 747 v.Add("until_date", strconv.FormatInt(config.UntilDate, 10)) 748 } 749 750 bot.debugLog("restrictChatMember", v, nil) 751 752 return bot.MakeRequest("restrictChatMember", v) 753 } 754 755 // PromoteChatMember add admin rights to user 756 func (bot *BotAPI) PromoteChatMember(config PromoteChatMemberConfig) (APIResponse, error) { 757 v := url.Values{} 758 759 if config.SuperGroupUsername != "" { 760 v.Add("chat_id", config.SuperGroupUsername) 761 } else if config.ChannelUsername != "" { 762 v.Add("chat_id", config.ChannelUsername) 763 } else { 764 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 765 } 766 v.Add("user_id", strconv.Itoa(config.UserID)) 767 768 if config.CanChangeInfo != nil { 769 v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo)) 770 } 771 if config.CanPostMessages != nil { 772 v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages)) 773 } 774 if config.CanEditMessages != nil { 775 v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages)) 776 } 777 if config.CanDeleteMessages != nil { 778 v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages)) 779 } 780 if config.CanInviteUsers != nil { 781 v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers)) 782 } 783 if config.CanRestrictMembers != nil { 784 v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers)) 785 } 786 if config.CanPinMessages != nil { 787 v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages)) 788 } 789 if config.CanPromoteMembers != nil { 790 v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers)) 791 } 792 793 bot.debugLog("promoteChatMember", v, nil) 794 795 return bot.MakeRequest("promoteChatMember", v) 796 } 797 798 // GetGameHighScores allows you to get the high scores for a game. 799 func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHighScore, error) { 800 v, _ := config.values() 801 802 resp, err := bot.MakeRequest(config.method(), v) 803 if err != nil { 804 return []GameHighScore{}, err 805 } 806 807 var highScores []GameHighScore 808 err = json.Unmarshal(resp.Result, &highScores) 809 810 return highScores, err 811 } 812 813 // AnswerShippingQuery allows you to reply to Update with shipping_query parameter. 814 func (bot *BotAPI) AnswerShippingQuery(config ShippingConfig) (APIResponse, error) { 815 v := url.Values{} 816 817 v.Add("shipping_query_id", config.ShippingQueryID) 818 v.Add("ok", strconv.FormatBool(config.OK)) 819 if config.OK == true { 820 data, err := json.Marshal(config.ShippingOptions) 821 if err != nil { 822 return APIResponse{}, err 823 } 824 v.Add("shipping_options", string(data)) 825 } else { 826 v.Add("error_message", config.ErrorMessage) 827 } 828 829 bot.debugLog("answerShippingQuery", v, nil) 830 831 return bot.MakeRequest("answerShippingQuery", v) 832 } 833 834 // AnswerPreCheckoutQuery allows you to reply to Update with pre_checkout_query. 835 func (bot *BotAPI) AnswerPreCheckoutQuery(config PreCheckoutConfig) (APIResponse, error) { 836 v := url.Values{} 837 838 v.Add("pre_checkout_query_id", config.PreCheckoutQueryID) 839 v.Add("ok", strconv.FormatBool(config.OK)) 840 if config.OK != true { 841 v.Add("error", config.ErrorMessage) 842 } 843 844 bot.debugLog("answerPreCheckoutQuery", v, nil) 845 846 return bot.MakeRequest("answerPreCheckoutQuery", v) 847 } 848 849 // DeleteMessage deletes a message in a chat 850 func (bot *BotAPI) DeleteMessage(config DeleteMessageConfig) (APIResponse, error) { 851 v, err := config.values() 852 if err != nil { 853 return APIResponse{}, err 854 } 855 856 bot.debugLog(config.method(), v, nil) 857 858 return bot.MakeRequest(config.method(), v) 859 } 860 861 // GetInviteLink get InviteLink for a chat 862 func (bot *BotAPI) GetInviteLink(config ChatConfig) (string, error) { 863 v := url.Values{} 864 865 if config.SuperGroupUsername == "" { 866 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) 867 } else { 868 v.Add("chat_id", config.SuperGroupUsername) 869 } 870 871 resp, err := bot.MakeRequest("exportChatInviteLink", v) 872 if err != nil { 873 return "", err 874 } 875 876 var inviteLink string 877 err = json.Unmarshal(resp.Result, &inviteLink) 878 879 return inviteLink, err 880 } 881 882 // PinChatMessage pin message in supergroup 883 func (bot *BotAPI) PinChatMessage(config PinChatMessageConfig) (APIResponse, error) { 884 v, err := config.values() 885 if err != nil { 886 return APIResponse{}, err 887 } 888 889 bot.debugLog(config.method(), v, nil) 890 891 return bot.MakeRequest(config.method(), v) 892 } 893 894 // UnpinChatMessage unpin message in supergroup 895 func (bot *BotAPI) UnpinChatMessage(config UnpinChatMessageConfig) (APIResponse, error) { 896 v, err := config.values() 897 if err != nil { 898 return APIResponse{}, err 899 } 900 901 bot.debugLog(config.method(), v, nil) 902 903 return bot.MakeRequest(config.method(), v) 904 } 905 906 // SetChatTitle change title of chat. 907 func (bot *BotAPI) SetChatTitle(config SetChatTitleConfig) (APIResponse, error) { 908 v, err := config.values() 909 if err != nil { 910 return APIResponse{}, err 911 } 912 913 bot.debugLog(config.method(), v, nil) 914 915 return bot.MakeRequest(config.method(), v) 916 } 917 918 // SetChatDescription change description of chat. 919 func (bot *BotAPI) SetChatDescription(config SetChatDescriptionConfig) (APIResponse, error) { 920 v, err := config.values() 921 if err != nil { 922 return APIResponse{}, err 923 } 924 925 bot.debugLog(config.method(), v, nil) 926 927 return bot.MakeRequest(config.method(), v) 928 } 929 930 // SetChatPhoto change photo of chat. 931 func (bot *BotAPI) SetChatPhoto(config SetChatPhotoConfig) (APIResponse, error) { 932 params, err := config.params() 933 if err != nil { 934 return APIResponse{}, err 935 } 936 937 file := config.getFile() 938 939 return bot.UploadFile(config.method(), params, config.name(), file) 940 } 941 942 // DeleteChatPhoto delete photo of chat. 943 func (bot *BotAPI) DeleteChatPhoto(config DeleteChatPhotoConfig) (APIResponse, error) { 944 v, err := config.values() 945 if err != nil { 946 return APIResponse{}, err 947 } 948 949 bot.debugLog(config.method(), v, nil) 950 951 return bot.MakeRequest(config.method(), v) 952 }