mirror of
https://github.com/ManyakRus/starter.git
synced 2025-11-26 23:10:42 +02:00
сделал telegram_bot
This commit is contained in:
1
go.mod
1
go.mod
@@ -64,6 +64,7 @@ require (
|
|||||||
github.com/go-faster/xor v1.0.0 // indirect
|
github.com/go-faster/xor v1.0.0 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect
|
||||||
github.com/go-test/deep v1.1.0 // indirect
|
github.com/go-test/deep v1.1.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/goccy/go-json v0.10.3 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -96,6 +96,8 @@ github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead5
|
|||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
|
||||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ type SettingsINI struct {
|
|||||||
// NamingStrategy - структура для хранения настроек наименования таблиц
|
// NamingStrategy - структура для хранения настроек наименования таблиц
|
||||||
var NamingStrategy = schema.NamingStrategy{}
|
var NamingStrategy = schema.NamingStrategy{}
|
||||||
|
|
||||||
// Connect_err - подключается к базе данных
|
// Connect - подключается к базе данных
|
||||||
func Connect() {
|
func Connect() {
|
||||||
|
|
||||||
if Settings.DB_HOST == "" {
|
if Settings.DB_HOST == "" {
|
||||||
@@ -66,16 +66,6 @@ func Connect() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogInfo_Connected - выводит сообщение в Лог, или паника при ошибке
|
|
||||||
func LogInfo_Connected(err error) {
|
|
||||||
if err != nil {
|
|
||||||
log.Panicln("POSTGRES gorm Connect() to database host: ", Settings.DB_HOST, ", Error: ", err)
|
|
||||||
} else {
|
|
||||||
log.Info("POSTGRES gorm Connected. host: ", Settings.DB_HOST, ", base name: ", Settings.DB_NAME, ", schema: ", Settings.DB_SCHEMA)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect_err - подключается к базе данных
|
// Connect_err - подключается к базе данных
|
||||||
func Connect_err() error {
|
func Connect_err() error {
|
||||||
var err error
|
var err error
|
||||||
@@ -628,3 +618,13 @@ func ReplaceTemporaryTableNamesToUnique(TextSQL string) string {
|
|||||||
func SetSingularTableNames(IsSingular bool) {
|
func SetSingularTableNames(IsSingular bool) {
|
||||||
NamingStrategy.SingularTable = IsSingular
|
NamingStrategy.SingularTable = IsSingular
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogInfo_Connected - выводит сообщение в Лог, или паника при ошибке
|
||||||
|
func LogInfo_Connected(err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Panicln("POSTGRES gorm Connect() to database host: ", Settings.DB_HOST, ", Error: ", err)
|
||||||
|
} else {
|
||||||
|
log.Info("POSTGRES gorm Connected. host: ", Settings.DB_HOST, ", base name: ", Settings.DB_NAME, ", schema: ", Settings.DB_SCHEMA)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
271
telegram_bot/telegram_bot.go
Normal file
271
telegram_bot/telegram_bot.go
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
package telegram_bot
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/ManyakRus/starter/contextmain"
|
||||||
|
"github.com/ManyakRus/starter/log"
|
||||||
|
"github.com/ManyakRus/starter/micro"
|
||||||
|
"github.com/ManyakRus/starter/stopapp"
|
||||||
|
botapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SettingsINI - структура для хранения всех нужных переменных окружения
|
||||||
|
type SettingsINI struct {
|
||||||
|
API_KEY string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings хранит все нужные переменные окружения
|
||||||
|
var Settings SettingsINI
|
||||||
|
|
||||||
|
// Client - клиент подклюенный к Telegram
|
||||||
|
var Client *botapi.BotAPI
|
||||||
|
|
||||||
|
// mutexReconnect - защита от многопоточности Reconnect()
|
||||||
|
var mutexReconnect = &sync.Mutex{}
|
||||||
|
|
||||||
|
// NeedReconnect - флаг необходимости переподключения
|
||||||
|
var NeedReconnect bool
|
||||||
|
|
||||||
|
// Connect - подключается к Telegram, или паника при ошибке
|
||||||
|
func Connect() {
|
||||||
|
|
||||||
|
if Settings.API_KEY == "" {
|
||||||
|
FillSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
err := Connect_err()
|
||||||
|
LogInfo_Connected(err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect_err - подключается к Telegram, возвращает ошибку
|
||||||
|
func Connect_err() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
Client, err = botapi.NewBotAPI(Settings.API_KEY)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
Client.Debug = false
|
||||||
|
|
||||||
|
//log.Printf("Authorized on account %s", bot.Self.UserName)
|
||||||
|
//
|
||||||
|
//u := botapi.NewUpdate(0)
|
||||||
|
//u.Timeout = 60
|
||||||
|
//
|
||||||
|
//updates := bot.GetUpdatesChan(u)
|
||||||
|
//var Users []User
|
||||||
|
//Users = make([]User, 0)
|
||||||
|
//
|
||||||
|
//for update := range updates {
|
||||||
|
// if update.Message == nil { // ignore any non-Message Updates
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
|
||||||
|
//
|
||||||
|
// TextFromUser := update.Message.Text
|
||||||
|
//
|
||||||
|
// Text := "Not understand. Fill name or phone number. "
|
||||||
|
// if valid.IsInt(TextFromUser) == true {
|
||||||
|
// Users = FindUser_by_Phone(TextFromUser)
|
||||||
|
// if len(Users) == 0 {
|
||||||
|
// Users = FindUser_by_CellPhone(TextFromUser)
|
||||||
|
// }
|
||||||
|
// } else if HaveAt(TextFromUser) == true {
|
||||||
|
// Users = FindUser_by_Email(TextFromUser)
|
||||||
|
// } else if valid.IsInt(TextFromUser) == false && HaveNumbers(TextFromUser) == false {
|
||||||
|
// Users = FindUser_by_Name(TextFromUser)
|
||||||
|
// if len(Users) == 0 {
|
||||||
|
// Users = FindUser_by_Post(TextFromUser)
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Users = FindUser_by_Adress(TextFromUser)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if len(Users) > 0 {
|
||||||
|
// Text = ""
|
||||||
|
// for _, User1 := range Users {
|
||||||
|
// Text = Text + User1.String() + "\n"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if len(Text) > 2000 {
|
||||||
|
// Text = Text[0:2000]
|
||||||
|
// Text = Text + "\n" + "..."
|
||||||
|
// Text = Text + "\n" + "..."
|
||||||
|
// Text = Text + "\n" + "..."
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// msg := botapi.NewMessage(update.Message.Chat.ID, Text)
|
||||||
|
// msg.ReplyToMessageID = update.Message.MessageID
|
||||||
|
// //msg.Entities = append(msg.Entities, )
|
||||||
|
// //append(msg.Entities, )
|
||||||
|
//
|
||||||
|
// bot.Send(msg)
|
||||||
|
//}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconnect повторное подключение к Telegram, если оно отключено
|
||||||
|
// или полная остановка программы
|
||||||
|
func Reconnect(err error) {
|
||||||
|
mutexReconnect.Lock()
|
||||||
|
defer mutexReconnect.Unlock()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, context.Canceled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if Client == nil {
|
||||||
|
log.Warn("Reconnect()")
|
||||||
|
err := Connect_err()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("error: ", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sError := err.Error()
|
||||||
|
if sError == "Conn closed" {
|
||||||
|
micro.Pause(1000)
|
||||||
|
log.Warn("Reconnect()")
|
||||||
|
err := Connect_err()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("error: ", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
////остановим программу т.к. она не должна работать при неработающеё БД
|
||||||
|
//log.Error("STOP app. Error: ", err)
|
||||||
|
//stopapp.StopApp()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseConnection - закрытие соединения с Telegram
|
||||||
|
func CloseConnection() {
|
||||||
|
if Client == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := CloseConnection_err()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Postgres gorm CloseConnection() error: ", err)
|
||||||
|
} else {
|
||||||
|
log.Info("Postgres gorm connection closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseConnection - закрытие соединения с Telegram, возвращает ошибку
|
||||||
|
func CloseConnection_err() error {
|
||||||
|
var err error
|
||||||
|
if Client == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
Client.StopReceivingUpdates()
|
||||||
|
Client = nil
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitStop - ожидает отмену глобального контекста
|
||||||
|
func WaitStop() {
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-contextmain.GetContext().Done():
|
||||||
|
log.Warn("Context app is canceled. telegram_bot")
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
stopapp.WaitTotalMessagesSendingNow("telegram_bot")
|
||||||
|
|
||||||
|
//
|
||||||
|
CloseConnection()
|
||||||
|
|
||||||
|
stopapp.GetWaitGroup_Main().Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start_ctx - необходимые процедуры для подключения к серверу Telegram
|
||||||
|
// Свой контекст и WaitGroup нужны для остановки работы сервиса Graceful shutdown
|
||||||
|
// Для тех кто пользуется этим репозиторием для старта и останова сервиса можно просто StartDB()
|
||||||
|
func Start_ctx(ctx *context.Context, WaitGroup *sync.WaitGroup) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
//запомним к себе контекст
|
||||||
|
contextmain.Ctx = ctx
|
||||||
|
if ctx == nil {
|
||||||
|
contextmain.GetContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
//запомним к себе WaitGroup
|
||||||
|
stopapp.SetWaitGroup_Main(WaitGroup)
|
||||||
|
if WaitGroup == nil {
|
||||||
|
stopapp.StartWaitStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
err = Connect_err()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
stopapp.GetWaitGroup_Main().Add(1)
|
||||||
|
go WaitStop()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start - делает соединение с Telegram, отключение и др.
|
||||||
|
func Start() {
|
||||||
|
err := Connect_err()
|
||||||
|
if err != nil {
|
||||||
|
log.Panic("telegram_bot Start() error: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stopapp.GetWaitGroup_Main().Add(1)
|
||||||
|
go WaitStop()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillSettings загружает переменные окружения в структуру из файла или из переменных окружения
|
||||||
|
func FillSettings() {
|
||||||
|
Settings = SettingsINI{}
|
||||||
|
|
||||||
|
// заполним из переменных оуружения
|
||||||
|
Settings.API_KEY = os.Getenv("API_KEY")
|
||||||
|
if Settings.API_KEY == "" {
|
||||||
|
log.Panicln("Need fill API_KEY ! in os.ENV ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConnection - возвращает соединение к нужной базе данных
|
||||||
|
func GetConnection() *botapi.BotAPI {
|
||||||
|
if Client == nil {
|
||||||
|
Connect()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo_Connected - выводит сообщение в Лог, или паника при ошибке
|
||||||
|
func LogInfo_Connected(err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("Telegram bot not connected with API KEY: %s, error: %w", Settings.API_KEY, err)
|
||||||
|
} else {
|
||||||
|
log.Info("Telegram bot Connected. With API KEY: %s", Settings.API_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
telegram_bot/telegram_bot_test.go
Normal file
1
telegram_bot/telegram_bot_test.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package telegram_bot
|
||||||
4
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/.gitignore
generated
vendored
Normal file
4
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.idea/
|
||||||
|
coverage.out
|
||||||
|
tmp/
|
||||||
|
book/
|
||||||
21
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/LICENSE.txt
generated
vendored
Normal file
21
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Syfaro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
121
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/README.md
generated
vendored
Normal file
121
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/README.md
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Golang bindings for the Telegram Bot API
|
||||||
|
|
||||||
|
[](https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api/v5)
|
||||||
|
[](https://github.com/go-telegram-bot-api/telegram-bot-api/actions/workflows/test.yml)
|
||||||
|
|
||||||
|
All methods are fairly self-explanatory, and reading the [godoc](https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api/v5) page should
|
||||||
|
explain everything. If something isn't clear, open an issue or submit
|
||||||
|
a pull request.
|
||||||
|
|
||||||
|
There are more tutorials and high-level information on the website, [go-telegram-bot-api.dev](https://go-telegram-bot-api.dev).
|
||||||
|
|
||||||
|
The scope of this project is just to provide a wrapper around the API
|
||||||
|
without any additional features. There are other projects for creating
|
||||||
|
something with plugins and command handlers without having to design
|
||||||
|
all that yourself.
|
||||||
|
|
||||||
|
Join [the development group](https://telegram.me/go_telegram_bot_api) if
|
||||||
|
you want to ask questions or discuss development.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
First, ensure the library is installed and up to date by running
|
||||||
|
`go get -u github.com/go-telegram-bot-api/telegram-bot-api/v5`.
|
||||||
|
|
||||||
|
This is a very simple bot that just displays any gotten updates,
|
||||||
|
then replies it to that chat.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.Debug = true
|
||||||
|
|
||||||
|
log.Printf("Authorized on account %s", bot.Self.UserName)
|
||||||
|
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
updates := bot.GetUpdatesChan(u)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
if update.Message != nil { // If we got a message
|
||||||
|
log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
|
||||||
|
msg.ReplyToMessageID = update.Message.MessageID
|
||||||
|
|
||||||
|
bot.Send(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to use webhooks (if you wish to run on Google App Engine),
|
||||||
|
you may use a slightly different method.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.Debug = true
|
||||||
|
|
||||||
|
log.Printf("Authorized on account %s", bot.Self.UserName)
|
||||||
|
|
||||||
|
wh, _ := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, "cert.pem")
|
||||||
|
|
||||||
|
_, err = bot.SetWebhook(wh)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := bot.GetWebhookInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.LastErrorDate != 0 {
|
||||||
|
log.Printf("Telegram callback failed: %s", info.LastErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := bot.ListenForWebhook("/" + bot.Token)
|
||||||
|
go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
log.Printf("%+v\n", update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need, you may generate a self-signed certificate, as this requires
|
||||||
|
HTTPS / TLS. The above example tells Telegram that this is your
|
||||||
|
certificate and that it should be trusted, even though it is not
|
||||||
|
properly signed.
|
||||||
|
|
||||||
|
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3560 -subj "//O=Org\CN=Test" -nodes
|
||||||
|
|
||||||
|
Now that [Let's Encrypt](https://letsencrypt.org) is available,
|
||||||
|
you may wish to generate your free TLS certificate there.
|
||||||
9
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/book.toml
generated
vendored
Normal file
9
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/book.toml
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[book]
|
||||||
|
authors = ["Syfaro"]
|
||||||
|
language = "en"
|
||||||
|
multilingual = false
|
||||||
|
src = "docs"
|
||||||
|
title = "Go Telegram Bot API"
|
||||||
|
|
||||||
|
[output.html]
|
||||||
|
git-repository-url = "https://github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
726
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/bot.go
generated
vendored
Normal file
726
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/bot.go
generated
vendored
Normal file
@@ -0,0 +1,726 @@
|
|||||||
|
// Package tgbotapi has functions and types used for interacting with
|
||||||
|
// the Telegram Bot API.
|
||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HTTPClient is the type needed for the bot to perform HTTP requests.
|
||||||
|
type HTTPClient interface {
|
||||||
|
Do(req *http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BotAPI allows you to interact with the Telegram Bot API.
|
||||||
|
type BotAPI struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Debug bool `json:"debug"`
|
||||||
|
Buffer int `json:"buffer"`
|
||||||
|
|
||||||
|
Self User `json:"-"`
|
||||||
|
Client HTTPClient `json:"-"`
|
||||||
|
shutdownChannel chan interface{}
|
||||||
|
|
||||||
|
apiEndpoint string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotAPI creates a new BotAPI instance.
|
||||||
|
//
|
||||||
|
// It requires a token, provided by @BotFather on Telegram.
|
||||||
|
func NewBotAPI(token string) (*BotAPI, error) {
|
||||||
|
return NewBotAPIWithClient(token, APIEndpoint, &http.Client{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotAPIWithAPIEndpoint creates a new BotAPI instance
|
||||||
|
// and allows you to pass API endpoint.
|
||||||
|
//
|
||||||
|
// It requires a token, provided by @BotFather on Telegram and API endpoint.
|
||||||
|
func NewBotAPIWithAPIEndpoint(token, apiEndpoint string) (*BotAPI, error) {
|
||||||
|
return NewBotAPIWithClient(token, apiEndpoint, &http.Client{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotAPIWithClient creates a new BotAPI instance
|
||||||
|
// and allows you to pass a http.Client.
|
||||||
|
//
|
||||||
|
// It requires a token, provided by @BotFather on Telegram and API endpoint.
|
||||||
|
func NewBotAPIWithClient(token, apiEndpoint string, client HTTPClient) (*BotAPI, error) {
|
||||||
|
bot := &BotAPI{
|
||||||
|
Token: token,
|
||||||
|
Client: client,
|
||||||
|
Buffer: 100,
|
||||||
|
shutdownChannel: make(chan interface{}),
|
||||||
|
|
||||||
|
apiEndpoint: apiEndpoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
self, err := bot.GetMe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.Self = self
|
||||||
|
|
||||||
|
return bot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAPIEndpoint changes the Telegram Bot API endpoint used by the instance.
|
||||||
|
func (bot *BotAPI) SetAPIEndpoint(apiEndpoint string) {
|
||||||
|
bot.apiEndpoint = apiEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildParams(in Params) url.Values {
|
||||||
|
if in == nil {
|
||||||
|
return url.Values{}
|
||||||
|
}
|
||||||
|
|
||||||
|
out := url.Values{}
|
||||||
|
|
||||||
|
for key, value := range in {
|
||||||
|
out.Set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeRequest makes a request to a specific endpoint with our token.
|
||||||
|
func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, error) {
|
||||||
|
if bot.Debug {
|
||||||
|
log.Printf("Endpoint: %s, params: %v\n", endpoint, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
method := fmt.Sprintf(bot.apiEndpoint, bot.Token, endpoint)
|
||||||
|
|
||||||
|
values := buildParams(params)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", method, strings.NewReader(values.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return &APIResponse{}, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
resp, err := bot.Client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
bytes, err := bot.decodeAPIResponse(resp.Body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
return &apiResp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if bot.Debug {
|
||||||
|
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !apiResp.Ok {
|
||||||
|
var parameters ResponseParameters
|
||||||
|
|
||||||
|
if apiResp.Parameters != nil {
|
||||||
|
parameters = *apiResp.Parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
return &apiResp, &Error{
|
||||||
|
Code: apiResp.ErrorCode,
|
||||||
|
Message: apiResp.Description,
|
||||||
|
ResponseParameters: parameters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, error) {
|
||||||
|
if !bot.Debug {
|
||||||
|
dec := json.NewDecoder(responseBody)
|
||||||
|
err := dec.Decode(resp)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// if debug, read response body
|
||||||
|
data, err := ioutil.ReadAll(responseBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadFiles makes a request to the API with files.
|
||||||
|
func (bot *BotAPI) UploadFiles(endpoint string, params Params, files []RequestFile) (*APIResponse, error) {
|
||||||
|
r, w := io.Pipe()
|
||||||
|
m := multipart.NewWriter(w)
|
||||||
|
|
||||||
|
// This code modified from the very helpful @HirbodBehnam
|
||||||
|
// https://github.com/go-telegram-bot-api/telegram-bot-api/issues/354#issuecomment-663856473
|
||||||
|
go func() {
|
||||||
|
defer w.Close()
|
||||||
|
defer m.Close()
|
||||||
|
|
||||||
|
for field, value := range params {
|
||||||
|
if err := m.WriteField(field, value); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Data.NeedsUpload() {
|
||||||
|
name, reader, err := file.Data.UploadData()
|
||||||
|
if err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
part, err := m.CreateFormFile(file.Name, name)
|
||||||
|
if err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.Copy(part, reader); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if closer, ok := reader.(io.ReadCloser); ok {
|
||||||
|
if err = closer.Close(); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value := file.Data.SendData()
|
||||||
|
|
||||||
|
if err := m.WriteField(file.Name, value); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if bot.Debug {
|
||||||
|
log.Printf("Endpoint: %s, params: %v, with %d files\n", endpoint, params, len(files))
|
||||||
|
}
|
||||||
|
|
||||||
|
method := fmt.Sprintf(bot.apiEndpoint, bot.Token, endpoint)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", method, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", m.FormDataContentType())
|
||||||
|
|
||||||
|
resp, err := bot.Client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
bytes, err := bot.decodeAPIResponse(resp.Body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
return &apiResp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if bot.Debug {
|
||||||
|
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !apiResp.Ok {
|
||||||
|
var parameters ResponseParameters
|
||||||
|
|
||||||
|
if apiResp.Parameters != nil {
|
||||||
|
parameters = *apiResp.Parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
return &apiResp, &Error{
|
||||||
|
Message: apiResp.Description,
|
||||||
|
ResponseParameters: parameters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &apiResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileDirectURL returns direct URL to file
|
||||||
|
//
|
||||||
|
// It requires the FileID.
|
||||||
|
func (bot *BotAPI) GetFileDirectURL(fileID string) (string, error) {
|
||||||
|
file, err := bot.GetFile(FileConfig{fileID})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.Link(bot.Token), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMe fetches the currently authenticated bot.
|
||||||
|
//
|
||||||
|
// This method is called upon creation to validate the token,
|
||||||
|
// and so you may get this data from BotAPI.Self without the need for
|
||||||
|
// another request.
|
||||||
|
func (bot *BotAPI) GetMe() (User, error) {
|
||||||
|
resp, err := bot.MakeRequest("getMe", nil)
|
||||||
|
if err != nil {
|
||||||
|
return User{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var user User
|
||||||
|
err = json.Unmarshal(resp.Result, &user)
|
||||||
|
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMessageToMe returns true if message directed to this bot.
|
||||||
|
//
|
||||||
|
// It requires the Message.
|
||||||
|
func (bot *BotAPI) IsMessageToMe(message Message) bool {
|
||||||
|
return strings.Contains(message.Text, "@"+bot.Self.UserName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasFilesNeedingUpload(files []RequestFile) bool {
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Data.NeedsUpload() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request sends a Chattable to Telegram, and returns the APIResponse.
|
||||||
|
func (bot *BotAPI) Request(c Chattable) (*APIResponse, error) {
|
||||||
|
params, err := c.params()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, ok := c.(Fileable); ok {
|
||||||
|
files := t.files()
|
||||||
|
|
||||||
|
// If we have files that need to be uploaded, we should delegate the
|
||||||
|
// request to UploadFile.
|
||||||
|
if hasFilesNeedingUpload(files) {
|
||||||
|
return bot.UploadFiles(t.method(), params, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
// However, if there are no files to be uploaded, there's likely things
|
||||||
|
// that need to be turned into params instead.
|
||||||
|
for _, file := range files {
|
||||||
|
params[file.Name] = file.Data.SendData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bot.MakeRequest(c.method(), params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send will send a Chattable item to Telegram and provides the
|
||||||
|
// returned Message.
|
||||||
|
func (bot *BotAPI) Send(c Chattable) (Message, error) {
|
||||||
|
resp, err := bot.Request(c)
|
||||||
|
if err != nil {
|
||||||
|
return Message{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var message Message
|
||||||
|
err = json.Unmarshal(resp.Result, &message)
|
||||||
|
|
||||||
|
return message, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMediaGroup sends a media group and returns the resulting messages.
|
||||||
|
func (bot *BotAPI) SendMediaGroup(config MediaGroupConfig) ([]Message, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var messages []Message
|
||||||
|
err = json.Unmarshal(resp.Result, &messages)
|
||||||
|
|
||||||
|
return messages, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserProfilePhotos gets a user's profile photos.
|
||||||
|
//
|
||||||
|
// It requires UserID.
|
||||||
|
// Offset and Limit are optional.
|
||||||
|
func (bot *BotAPI) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return UserProfilePhotos{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var profilePhotos UserProfilePhotos
|
||||||
|
err = json.Unmarshal(resp.Result, &profilePhotos)
|
||||||
|
|
||||||
|
return profilePhotos, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFile returns a File which can download a file from Telegram.
|
||||||
|
//
|
||||||
|
// Requires FileID.
|
||||||
|
func (bot *BotAPI) GetFile(config FileConfig) (File, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return File{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var file File
|
||||||
|
err = json.Unmarshal(resp.Result, &file)
|
||||||
|
|
||||||
|
return file, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpdates fetches updates.
|
||||||
|
// If a WebHook is set, this will not return any data!
|
||||||
|
//
|
||||||
|
// Offset, Limit, Timeout, and AllowedUpdates are optional.
|
||||||
|
// To avoid stale items, set Offset to one higher than the previous item.
|
||||||
|
// Set Timeout to a large number to reduce requests, so you can get updates
|
||||||
|
// instantly instead of having to wait between requests.
|
||||||
|
func (bot *BotAPI) GetUpdates(config UpdateConfig) ([]Update, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return []Update{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var updates []Update
|
||||||
|
err = json.Unmarshal(resp.Result, &updates)
|
||||||
|
|
||||||
|
return updates, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWebhookInfo allows you to fetch information about a webhook and if
|
||||||
|
// one currently is set, along with pending update count and error messages.
|
||||||
|
func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
||||||
|
resp, err := bot.MakeRequest("getWebhookInfo", nil)
|
||||||
|
if err != nil {
|
||||||
|
return WebhookInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var info WebhookInfo
|
||||||
|
err = json.Unmarshal(resp.Result, &info)
|
||||||
|
|
||||||
|
return info, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||||
|
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
|
||||||
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-bot.shutdownChannel:
|
||||||
|
close(ch)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
updates, err := bot.GetUpdates(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
log.Println("Failed to get updates, retrying in 3 seconds...")
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, update := range updates {
|
||||||
|
if update.UpdateID >= config.Offset {
|
||||||
|
config.Offset = update.UpdateID + 1
|
||||||
|
ch <- update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopReceivingUpdates stops the go routine which receives updates
|
||||||
|
func (bot *BotAPI) StopReceivingUpdates() {
|
||||||
|
if bot.Debug {
|
||||||
|
log.Println("Stopping the update receiver routine...")
|
||||||
|
}
|
||||||
|
close(bot.shutdownChannel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenForWebhook registers a http handler for a webhook.
|
||||||
|
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||||
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
|
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
update, err := bot.HandleUpdate(r)
|
||||||
|
if err != nil {
|
||||||
|
errMsg, _ := json.Marshal(map[string]string{"error": err.Error()})
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write(errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- *update
|
||||||
|
})
|
||||||
|
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenForWebhookRespReqFormat registers a http handler for a single incoming webhook.
|
||||||
|
func (bot *BotAPI) ListenForWebhookRespReqFormat(w http.ResponseWriter, r *http.Request) UpdatesChannel {
|
||||||
|
ch := make(chan Update, bot.Buffer)
|
||||||
|
|
||||||
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
update, err := bot.HandleUpdate(r)
|
||||||
|
if err != nil {
|
||||||
|
errMsg, _ := json.Marshal(map[string]string{"error": err.Error()})
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write(errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- *update
|
||||||
|
close(ch)
|
||||||
|
}(w, r)
|
||||||
|
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUpdate parses and returns update received via webhook
|
||||||
|
func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
err := errors.New("wrong HTTP method required POST")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var update Update
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&update)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &update, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteToHTTPResponse writes the request to the HTTP ResponseWriter.
|
||||||
|
//
|
||||||
|
// It doesn't support uploading files.
|
||||||
|
//
|
||||||
|
// See https://core.telegram.org/bots/api#making-requests-when-getting-updates
|
||||||
|
// for details.
|
||||||
|
func WriteToHTTPResponse(w http.ResponseWriter, c Chattable) error {
|
||||||
|
params, err := c.params()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, ok := c.(Fileable); ok {
|
||||||
|
if hasFilesNeedingUpload(t.files()) {
|
||||||
|
return errors.New("unable to use http response to upload files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
values := buildParams(params)
|
||||||
|
values.Set("method", c.method())
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
_, err = w.Write([]byte(values.Encode()))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChat gets information about a chat.
|
||||||
|
func (bot *BotAPI) GetChat(config ChatInfoConfig) (Chat, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return Chat{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var chat Chat
|
||||||
|
err = json.Unmarshal(resp.Result, &chat)
|
||||||
|
|
||||||
|
return chat, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatAdministrators gets a list of administrators in the chat.
|
||||||
|
//
|
||||||
|
// If none have been appointed, only the creator will be returned.
|
||||||
|
// Bots are not shown, even if they are an administrator.
|
||||||
|
func (bot *BotAPI) GetChatAdministrators(config ChatAdministratorsConfig) ([]ChatMember, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return []ChatMember{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var members []ChatMember
|
||||||
|
err = json.Unmarshal(resp.Result, &members)
|
||||||
|
|
||||||
|
return members, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMembersCount gets the number of users in a chat.
|
||||||
|
func (bot *BotAPI) GetChatMembersCount(config ChatMemberCountConfig) (int, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = json.Unmarshal(resp.Result, &count)
|
||||||
|
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMember gets a specific chat member.
|
||||||
|
func (bot *BotAPI) GetChatMember(config GetChatMemberConfig) (ChatMember, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return ChatMember{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var member ChatMember
|
||||||
|
err = json.Unmarshal(resp.Result, &member)
|
||||||
|
|
||||||
|
return member, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGameHighScores allows you to get the high scores for a game.
|
||||||
|
func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHighScore, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return []GameHighScore{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var highScores []GameHighScore
|
||||||
|
err = json.Unmarshal(resp.Result, &highScores)
|
||||||
|
|
||||||
|
return highScores, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInviteLink get InviteLink for a chat
|
||||||
|
func (bot *BotAPI) GetInviteLink(config ChatInviteLinkConfig) (string, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var inviteLink string
|
||||||
|
err = json.Unmarshal(resp.Result, &inviteLink)
|
||||||
|
|
||||||
|
return inviteLink, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStickerSet returns a StickerSet.
|
||||||
|
func (bot *BotAPI) GetStickerSet(config GetStickerSetConfig) (StickerSet, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return StickerSet{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var stickers StickerSet
|
||||||
|
err = json.Unmarshal(resp.Result, &stickers)
|
||||||
|
|
||||||
|
return stickers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopPoll stops a poll and returns the result.
|
||||||
|
func (bot *BotAPI) StopPoll(config StopPollConfig) (Poll, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return Poll{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var poll Poll
|
||||||
|
err = json.Unmarshal(resp.Result, &poll)
|
||||||
|
|
||||||
|
return poll, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyCommands gets the currently registered commands.
|
||||||
|
func (bot *BotAPI) GetMyCommands() ([]BotCommand, error) {
|
||||||
|
return bot.GetMyCommandsWithConfig(GetMyCommandsConfig{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMyCommandsWithConfig gets the currently registered commands with a config.
|
||||||
|
func (bot *BotAPI) GetMyCommandsWithConfig(config GetMyCommandsConfig) ([]BotCommand, error) {
|
||||||
|
resp, err := bot.Request(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var commands []BotCommand
|
||||||
|
err = json.Unmarshal(resp.Result, &commands)
|
||||||
|
|
||||||
|
return commands, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyMessage copy messages of any kind. The method is analogous to the method
|
||||||
|
// forwardMessage, but the copied message doesn't have a link to the original
|
||||||
|
// message. Returns the MessageID of the sent message on success.
|
||||||
|
func (bot *BotAPI) CopyMessage(config CopyMessageConfig) (MessageID, error) {
|
||||||
|
params, err := config.params()
|
||||||
|
if err != nil {
|
||||||
|
return MessageID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.MakeRequest(config.method(), params)
|
||||||
|
if err != nil {
|
||||||
|
return MessageID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var messageID MessageID
|
||||||
|
err = json.Unmarshal(resp.Result, &messageID)
|
||||||
|
|
||||||
|
return messageID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EscapeText takes an input text and escape Telegram markup symbols.
|
||||||
|
// In this way we can send a text without being afraid of having to escape the characters manually.
|
||||||
|
// Note that you don't have to include the formatting style in the input text, or it will be escaped too.
|
||||||
|
// If there is an error, an empty string will be returned.
|
||||||
|
//
|
||||||
|
// parseMode is the text formatting mode (ModeMarkdown, ModeMarkdownV2 or ModeHTML)
|
||||||
|
// text is the input string that will be escaped
|
||||||
|
func EscapeText(parseMode string, text string) string {
|
||||||
|
var replacer *strings.Replacer
|
||||||
|
|
||||||
|
if parseMode == ModeHTML {
|
||||||
|
replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&")
|
||||||
|
} else if parseMode == ModeMarkdown {
|
||||||
|
replacer = strings.NewReplacer("_", "\\_", "*", "\\*", "`", "\\`", "[", "\\[")
|
||||||
|
} else if parseMode == ModeMarkdownV2 {
|
||||||
|
replacer = strings.NewReplacer(
|
||||||
|
"_", "\\_", "*", "\\*", "[", "\\[", "]", "\\]", "(",
|
||||||
|
"\\(", ")", "\\)", "~", "\\~", "`", "\\`", ">", "\\>",
|
||||||
|
"#", "\\#", "+", "\\+", "-", "\\-", "=", "\\=", "|",
|
||||||
|
"\\|", "{", "\\{", "}", "\\}", ".", "\\.", "!", "\\!",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return replacer.Replace(text)
|
||||||
|
}
|
||||||
2468
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/configs.go
generated
vendored
Normal file
2468
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/configs.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
927
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/helpers.go
generated
vendored
Normal file
927
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,927 @@
|
|||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewMessage creates a new Message.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, text is the message text.
|
||||||
|
func NewMessage(chatID int64, text string) MessageConfig {
|
||||||
|
return MessageConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
ReplyToMessageID: 0,
|
||||||
|
},
|
||||||
|
Text: text,
|
||||||
|
DisableWebPagePreview: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteMessage creates a request to delete a message.
|
||||||
|
func NewDeleteMessage(chatID int64, messageID int) DeleteMessageConfig {
|
||||||
|
return DeleteMessageConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessageToChannel creates a new Message that is sent to a channel
|
||||||
|
// by username.
|
||||||
|
//
|
||||||
|
// username is the username of the channel, text is the message text,
|
||||||
|
// and the username should be in the form of `@username`.
|
||||||
|
func NewMessageToChannel(username string, text string) MessageConfig {
|
||||||
|
return MessageConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChannelUsername: username,
|
||||||
|
},
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForward creates a new forward.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, fromChatID is the source chat,
|
||||||
|
// and messageID is the ID of the original message.
|
||||||
|
func NewForward(chatID int64, fromChatID int64, messageID int) ForwardConfig {
|
||||||
|
return ForwardConfig{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
FromChatID: fromChatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCopyMessage creates a new copy message.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, fromChatID is the source chat,
|
||||||
|
// and messageID is the ID of the original message.
|
||||||
|
func NewCopyMessage(chatID int64, fromChatID int64, messageID int) CopyMessageConfig {
|
||||||
|
return CopyMessageConfig{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
FromChatID: fromChatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPhoto creates a new sendPhoto request.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, file is a string path to the file,
|
||||||
|
// FileReader, or FileBytes.
|
||||||
|
//
|
||||||
|
// Note that you must send animated GIFs as a document.
|
||||||
|
func NewPhoto(chatID int64, file RequestFileData) PhotoConfig {
|
||||||
|
return PhotoConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPhotoToChannel creates a new photo uploader to send a photo to a channel.
|
||||||
|
//
|
||||||
|
// Note that you must send animated GIFs as a document.
|
||||||
|
func NewPhotoToChannel(username string, file RequestFileData) PhotoConfig {
|
||||||
|
return PhotoConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChannelUsername: username,
|
||||||
|
},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAudio creates a new sendAudio request.
|
||||||
|
func NewAudio(chatID int64, file RequestFileData) AudioConfig {
|
||||||
|
return AudioConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDocument creates a new sendDocument request.
|
||||||
|
func NewDocument(chatID int64, file RequestFileData) DocumentConfig {
|
||||||
|
return DocumentConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSticker creates a new sendSticker request.
|
||||||
|
func NewSticker(chatID int64, file RequestFileData) StickerConfig {
|
||||||
|
return StickerConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVideo creates a new sendVideo request.
|
||||||
|
func NewVideo(chatID int64, file RequestFileData) VideoConfig {
|
||||||
|
return VideoConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnimation creates a new sendAnimation request.
|
||||||
|
func NewAnimation(chatID int64, file RequestFileData) AnimationConfig {
|
||||||
|
return AnimationConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVideoNote creates a new sendVideoNote request.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, file is a string path to the file,
|
||||||
|
// FileReader, or FileBytes.
|
||||||
|
func NewVideoNote(chatID int64, length int, file RequestFileData) VideoNoteConfig {
|
||||||
|
return VideoNoteConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
Length: length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVoice creates a new sendVoice request.
|
||||||
|
func NewVoice(chatID int64, file RequestFileData) VoiceConfig {
|
||||||
|
return VoiceConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
File: file,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMediaGroup creates a new media group. Files should be an array of
|
||||||
|
// two to ten InputMediaPhoto or InputMediaVideo.
|
||||||
|
func NewMediaGroup(chatID int64, files []interface{}) MediaGroupConfig {
|
||||||
|
return MediaGroupConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
Media: files,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInputMediaPhoto creates a new InputMediaPhoto.
|
||||||
|
func NewInputMediaPhoto(media RequestFileData) InputMediaPhoto {
|
||||||
|
return InputMediaPhoto{
|
||||||
|
BaseInputMedia{
|
||||||
|
Type: "photo",
|
||||||
|
Media: media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInputMediaVideo creates a new InputMediaVideo.
|
||||||
|
func NewInputMediaVideo(media RequestFileData) InputMediaVideo {
|
||||||
|
return InputMediaVideo{
|
||||||
|
BaseInputMedia: BaseInputMedia{
|
||||||
|
Type: "video",
|
||||||
|
Media: media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInputMediaAnimation creates a new InputMediaAnimation.
|
||||||
|
func NewInputMediaAnimation(media RequestFileData) InputMediaAnimation {
|
||||||
|
return InputMediaAnimation{
|
||||||
|
BaseInputMedia: BaseInputMedia{
|
||||||
|
Type: "animation",
|
||||||
|
Media: media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInputMediaAudio creates a new InputMediaAudio.
|
||||||
|
func NewInputMediaAudio(media RequestFileData) InputMediaAudio {
|
||||||
|
return InputMediaAudio{
|
||||||
|
BaseInputMedia: BaseInputMedia{
|
||||||
|
Type: "audio",
|
||||||
|
Media: media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInputMediaDocument creates a new InputMediaDocument.
|
||||||
|
func NewInputMediaDocument(media RequestFileData) InputMediaDocument {
|
||||||
|
return InputMediaDocument{
|
||||||
|
BaseInputMedia: BaseInputMedia{
|
||||||
|
Type: "document",
|
||||||
|
Media: media,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContact allows you to send a shared contact.
|
||||||
|
func NewContact(chatID int64, phoneNumber, firstName string) ContactConfig {
|
||||||
|
return ContactConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
PhoneNumber: phoneNumber,
|
||||||
|
FirstName: firstName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocation shares your location.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, latitude and longitude are coordinates.
|
||||||
|
func NewLocation(chatID int64, latitude float64, longitude float64) LocationConfig {
|
||||||
|
return LocationConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVenue allows you to send a venue and its location.
|
||||||
|
func NewVenue(chatID int64, title, address string, latitude, longitude float64) VenueConfig {
|
||||||
|
return VenueConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
Title: title,
|
||||||
|
Address: address,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewChatAction sets a chat action.
|
||||||
|
// Actions last for 5 seconds, or until your next action.
|
||||||
|
//
|
||||||
|
// chatID is where to send it, action should be set via Chat constants.
|
||||||
|
func NewChatAction(chatID int64, action string) ChatActionConfig {
|
||||||
|
return ChatActionConfig{
|
||||||
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
Action: action,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUserProfilePhotos gets user profile photos.
|
||||||
|
//
|
||||||
|
// userID is the ID of the user you wish to get profile photos from.
|
||||||
|
func NewUserProfilePhotos(userID int64) UserProfilePhotosConfig {
|
||||||
|
return UserProfilePhotosConfig{
|
||||||
|
UserID: userID,
|
||||||
|
Offset: 0,
|
||||||
|
Limit: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUpdate gets updates since the last Offset.
|
||||||
|
//
|
||||||
|
// offset is the last Update ID to include.
|
||||||
|
// You likely want to set this to the last Update ID plus 1.
|
||||||
|
func NewUpdate(offset int) UpdateConfig {
|
||||||
|
return UpdateConfig{
|
||||||
|
Offset: offset,
|
||||||
|
Limit: 0,
|
||||||
|
Timeout: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebhook creates a new webhook.
|
||||||
|
//
|
||||||
|
// link is the url parsable link you wish to get the updates.
|
||||||
|
func NewWebhook(link string) (WebhookConfig, error) {
|
||||||
|
u, err := url.Parse(link)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return WebhookConfig{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return WebhookConfig{
|
||||||
|
URL: u,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebhookWithCert creates a new webhook with a certificate.
|
||||||
|
//
|
||||||
|
// link is the url you wish to get webhooks,
|
||||||
|
// file contains a string to a file, FileReader, or FileBytes.
|
||||||
|
func NewWebhookWithCert(link string, file RequestFileData) (WebhookConfig, error) {
|
||||||
|
u, err := url.Parse(link)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return WebhookConfig{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return WebhookConfig{
|
||||||
|
URL: u,
|
||||||
|
Certificate: file,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultArticle creates a new inline query article.
|
||||||
|
func NewInlineQueryResultArticle(id, title, messageText string) InlineQueryResultArticle {
|
||||||
|
return InlineQueryResultArticle{
|
||||||
|
Type: "article",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
InputMessageContent: InputTextMessageContent{
|
||||||
|
Text: messageText,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultArticleMarkdown creates a new inline query article with Markdown parsing.
|
||||||
|
func NewInlineQueryResultArticleMarkdown(id, title, messageText string) InlineQueryResultArticle {
|
||||||
|
return InlineQueryResultArticle{
|
||||||
|
Type: "article",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
InputMessageContent: InputTextMessageContent{
|
||||||
|
Text: messageText,
|
||||||
|
ParseMode: "Markdown",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultArticleMarkdownV2 creates a new inline query article with MarkdownV2 parsing.
|
||||||
|
func NewInlineQueryResultArticleMarkdownV2(id, title, messageText string) InlineQueryResultArticle {
|
||||||
|
return InlineQueryResultArticle{
|
||||||
|
Type: "article",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
InputMessageContent: InputTextMessageContent{
|
||||||
|
Text: messageText,
|
||||||
|
ParseMode: "MarkdownV2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultArticleHTML creates a new inline query article with HTML parsing.
|
||||||
|
func NewInlineQueryResultArticleHTML(id, title, messageText string) InlineQueryResultArticle {
|
||||||
|
return InlineQueryResultArticle{
|
||||||
|
Type: "article",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
InputMessageContent: InputTextMessageContent{
|
||||||
|
Text: messageText,
|
||||||
|
ParseMode: "HTML",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultGIF creates a new inline query GIF.
|
||||||
|
func NewInlineQueryResultGIF(id, url string) InlineQueryResultGIF {
|
||||||
|
return InlineQueryResultGIF{
|
||||||
|
Type: "gif",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedGIF create a new inline query with cached photo.
|
||||||
|
func NewInlineQueryResultCachedGIF(id, gifID string) InlineQueryResultCachedGIF {
|
||||||
|
return InlineQueryResultCachedGIF{
|
||||||
|
Type: "gif",
|
||||||
|
ID: id,
|
||||||
|
GIFID: gifID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultMPEG4GIF creates a new inline query MPEG4 GIF.
|
||||||
|
func NewInlineQueryResultMPEG4GIF(id, url string) InlineQueryResultMPEG4GIF {
|
||||||
|
return InlineQueryResultMPEG4GIF{
|
||||||
|
Type: "mpeg4_gif",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedMPEG4GIF create a new inline query with cached MPEG4 GIF.
|
||||||
|
func NewInlineQueryResultCachedMPEG4GIF(id, MPEG4GIFID string) InlineQueryResultCachedMPEG4GIF {
|
||||||
|
return InlineQueryResultCachedMPEG4GIF{
|
||||||
|
Type: "mpeg4_gif",
|
||||||
|
ID: id,
|
||||||
|
MPEG4FileID: MPEG4GIFID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultPhoto creates a new inline query photo.
|
||||||
|
func NewInlineQueryResultPhoto(id, url string) InlineQueryResultPhoto {
|
||||||
|
return InlineQueryResultPhoto{
|
||||||
|
Type: "photo",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultPhotoWithThumb creates a new inline query photo.
|
||||||
|
func NewInlineQueryResultPhotoWithThumb(id, url, thumb string) InlineQueryResultPhoto {
|
||||||
|
return InlineQueryResultPhoto{
|
||||||
|
Type: "photo",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
ThumbURL: thumb,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedPhoto create a new inline query with cached photo.
|
||||||
|
func NewInlineQueryResultCachedPhoto(id, photoID string) InlineQueryResultCachedPhoto {
|
||||||
|
return InlineQueryResultCachedPhoto{
|
||||||
|
Type: "photo",
|
||||||
|
ID: id,
|
||||||
|
PhotoID: photoID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultVideo creates a new inline query video.
|
||||||
|
func NewInlineQueryResultVideo(id, url string) InlineQueryResultVideo {
|
||||||
|
return InlineQueryResultVideo{
|
||||||
|
Type: "video",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedVideo create a new inline query with cached video.
|
||||||
|
func NewInlineQueryResultCachedVideo(id, videoID, title string) InlineQueryResultCachedVideo {
|
||||||
|
return InlineQueryResultCachedVideo{
|
||||||
|
Type: "video",
|
||||||
|
ID: id,
|
||||||
|
VideoID: videoID,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedSticker create a new inline query with cached sticker.
|
||||||
|
func NewInlineQueryResultCachedSticker(id, stickerID, title string) InlineQueryResultCachedSticker {
|
||||||
|
return InlineQueryResultCachedSticker{
|
||||||
|
Type: "sticker",
|
||||||
|
ID: id,
|
||||||
|
StickerID: stickerID,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultAudio creates a new inline query audio.
|
||||||
|
func NewInlineQueryResultAudio(id, url, title string) InlineQueryResultAudio {
|
||||||
|
return InlineQueryResultAudio{
|
||||||
|
Type: "audio",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedAudio create a new inline query with cached photo.
|
||||||
|
func NewInlineQueryResultCachedAudio(id, audioID string) InlineQueryResultCachedAudio {
|
||||||
|
return InlineQueryResultCachedAudio{
|
||||||
|
Type: "audio",
|
||||||
|
ID: id,
|
||||||
|
AudioID: audioID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultVoice creates a new inline query voice.
|
||||||
|
func NewInlineQueryResultVoice(id, url, title string) InlineQueryResultVoice {
|
||||||
|
return InlineQueryResultVoice{
|
||||||
|
Type: "voice",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedVoice create a new inline query with cached photo.
|
||||||
|
func NewInlineQueryResultCachedVoice(id, voiceID, title string) InlineQueryResultCachedVoice {
|
||||||
|
return InlineQueryResultCachedVoice{
|
||||||
|
Type: "voice",
|
||||||
|
ID: id,
|
||||||
|
VoiceID: voiceID,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultDocument creates a new inline query document.
|
||||||
|
func NewInlineQueryResultDocument(id, url, title, mimeType string) InlineQueryResultDocument {
|
||||||
|
return InlineQueryResultDocument{
|
||||||
|
Type: "document",
|
||||||
|
ID: id,
|
||||||
|
URL: url,
|
||||||
|
Title: title,
|
||||||
|
MimeType: mimeType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultCachedDocument create a new inline query with cached photo.
|
||||||
|
func NewInlineQueryResultCachedDocument(id, documentID, title string) InlineQueryResultCachedDocument {
|
||||||
|
return InlineQueryResultCachedDocument{
|
||||||
|
Type: "document",
|
||||||
|
ID: id,
|
||||||
|
DocumentID: documentID,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultLocation creates a new inline query location.
|
||||||
|
func NewInlineQueryResultLocation(id, title string, latitude, longitude float64) InlineQueryResultLocation {
|
||||||
|
return InlineQueryResultLocation{
|
||||||
|
Type: "location",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineQueryResultVenue creates a new inline query venue.
|
||||||
|
func NewInlineQueryResultVenue(id, title, address string, latitude, longitude float64) InlineQueryResultVenue {
|
||||||
|
return InlineQueryResultVenue{
|
||||||
|
Type: "venue",
|
||||||
|
ID: id,
|
||||||
|
Title: title,
|
||||||
|
Address: address,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEditMessageText allows you to edit the text of a message.
|
||||||
|
func NewEditMessageText(chatID int64, messageID int, text string) EditMessageTextConfig {
|
||||||
|
return EditMessageTextConfig{
|
||||||
|
BaseEdit: BaseEdit{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
},
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEditMessageTextAndMarkup allows you to edit the text and replymarkup of a message.
|
||||||
|
func NewEditMessageTextAndMarkup(chatID int64, messageID int, text string, replyMarkup InlineKeyboardMarkup) EditMessageTextConfig {
|
||||||
|
return EditMessageTextConfig{
|
||||||
|
BaseEdit: BaseEdit{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
ReplyMarkup: &replyMarkup,
|
||||||
|
},
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEditMessageCaption allows you to edit the caption of a message.
|
||||||
|
func NewEditMessageCaption(chatID int64, messageID int, caption string) EditMessageCaptionConfig {
|
||||||
|
return EditMessageCaptionConfig{
|
||||||
|
BaseEdit: BaseEdit{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
},
|
||||||
|
Caption: caption,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEditMessageReplyMarkup allows you to edit the inline
|
||||||
|
// keyboard markup.
|
||||||
|
func NewEditMessageReplyMarkup(chatID int64, messageID int, replyMarkup InlineKeyboardMarkup) EditMessageReplyMarkupConfig {
|
||||||
|
return EditMessageReplyMarkupConfig{
|
||||||
|
BaseEdit: BaseEdit{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
ReplyMarkup: &replyMarkup,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRemoveKeyboard hides the keyboard, with the option for being selective
|
||||||
|
// or hiding for everyone.
|
||||||
|
func NewRemoveKeyboard(selective bool) ReplyKeyboardRemove {
|
||||||
|
return ReplyKeyboardRemove{
|
||||||
|
RemoveKeyboard: true,
|
||||||
|
Selective: selective,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyboardButton creates a regular keyboard button.
|
||||||
|
func NewKeyboardButton(text string) KeyboardButton {
|
||||||
|
return KeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyboardButtonContact creates a keyboard button that requests
|
||||||
|
// user contact information upon click.
|
||||||
|
func NewKeyboardButtonContact(text string) KeyboardButton {
|
||||||
|
return KeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
RequestContact: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyboardButtonLocation creates a keyboard button that requests
|
||||||
|
// user location information upon click.
|
||||||
|
func NewKeyboardButtonLocation(text string) KeyboardButton {
|
||||||
|
return KeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
RequestLocation: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyboardButtonRow creates a row of keyboard buttons.
|
||||||
|
func NewKeyboardButtonRow(buttons ...KeyboardButton) []KeyboardButton {
|
||||||
|
var row []KeyboardButton
|
||||||
|
|
||||||
|
row = append(row, buttons...)
|
||||||
|
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReplyKeyboard creates a new regular keyboard with sane defaults.
|
||||||
|
func NewReplyKeyboard(rows ...[]KeyboardButton) ReplyKeyboardMarkup {
|
||||||
|
var keyboard [][]KeyboardButton
|
||||||
|
|
||||||
|
keyboard = append(keyboard, rows...)
|
||||||
|
|
||||||
|
return ReplyKeyboardMarkup{
|
||||||
|
ResizeKeyboard: true,
|
||||||
|
Keyboard: keyboard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOneTimeReplyKeyboard creates a new one time keyboard.
|
||||||
|
func NewOneTimeReplyKeyboard(rows ...[]KeyboardButton) ReplyKeyboardMarkup {
|
||||||
|
markup := NewReplyKeyboard(rows...)
|
||||||
|
markup.OneTimeKeyboard = true
|
||||||
|
return markup
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardButtonData creates an inline keyboard button with text
|
||||||
|
// and data for a callback.
|
||||||
|
func NewInlineKeyboardButtonData(text, data string) InlineKeyboardButton {
|
||||||
|
return InlineKeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
CallbackData: &data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardButtonLoginURL creates an inline keyboard button with text
|
||||||
|
// which goes to a LoginURL.
|
||||||
|
func NewInlineKeyboardButtonLoginURL(text string, loginURL LoginURL) InlineKeyboardButton {
|
||||||
|
return InlineKeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
LoginURL: &loginURL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardButtonURL creates an inline keyboard button with text
|
||||||
|
// which goes to a URL.
|
||||||
|
func NewInlineKeyboardButtonURL(text, url string) InlineKeyboardButton {
|
||||||
|
return InlineKeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
URL: &url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardButtonSwitch creates an inline keyboard button with
|
||||||
|
// text which allows the user to switch to a chat or return to a chat.
|
||||||
|
func NewInlineKeyboardButtonSwitch(text, sw string) InlineKeyboardButton {
|
||||||
|
return InlineKeyboardButton{
|
||||||
|
Text: text,
|
||||||
|
SwitchInlineQuery: &sw,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardRow creates an inline keyboard row with buttons.
|
||||||
|
func NewInlineKeyboardRow(buttons ...InlineKeyboardButton) []InlineKeyboardButton {
|
||||||
|
var row []InlineKeyboardButton
|
||||||
|
|
||||||
|
row = append(row, buttons...)
|
||||||
|
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInlineKeyboardMarkup creates a new inline keyboard.
|
||||||
|
func NewInlineKeyboardMarkup(rows ...[]InlineKeyboardButton) InlineKeyboardMarkup {
|
||||||
|
var keyboard [][]InlineKeyboardButton
|
||||||
|
|
||||||
|
keyboard = append(keyboard, rows...)
|
||||||
|
|
||||||
|
return InlineKeyboardMarkup{
|
||||||
|
InlineKeyboard: keyboard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCallback creates a new callback message.
|
||||||
|
func NewCallback(id, text string) CallbackConfig {
|
||||||
|
return CallbackConfig{
|
||||||
|
CallbackQueryID: id,
|
||||||
|
Text: text,
|
||||||
|
ShowAlert: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCallbackWithAlert creates a new callback message that alerts
|
||||||
|
// the user.
|
||||||
|
func NewCallbackWithAlert(id, text string) CallbackConfig {
|
||||||
|
return CallbackConfig{
|
||||||
|
CallbackQueryID: id,
|
||||||
|
Text: text,
|
||||||
|
ShowAlert: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInvoice creates 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}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewChatTitle allows you to update the title of a chat.
|
||||||
|
func NewChatTitle(chatID int64, title string) SetChatTitleConfig {
|
||||||
|
return SetChatTitleConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
Title: title,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewChatDescription allows you to update the description of a chat.
|
||||||
|
func NewChatDescription(chatID int64, description string) SetChatDescriptionConfig {
|
||||||
|
return SetChatDescriptionConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
Description: description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewChatPhoto allows you to update the photo for a chat.
|
||||||
|
func NewChatPhoto(chatID int64, photo RequestFileData) SetChatPhotoConfig {
|
||||||
|
return SetChatPhotoConfig{
|
||||||
|
BaseFile: BaseFile{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
File: photo,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteChatPhoto allows you to delete the photo for a chat.
|
||||||
|
func NewDeleteChatPhoto(chatID int64) DeleteChatPhotoConfig {
|
||||||
|
return DeleteChatPhotoConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPoll allows you to create a new poll.
|
||||||
|
func NewPoll(chatID int64, question string, options ...string) SendPollConfig {
|
||||||
|
return SendPollConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
Question: question,
|
||||||
|
Options: options,
|
||||||
|
IsAnonymous: true, // This is Telegram's default.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStopPoll allows you to stop a poll.
|
||||||
|
func NewStopPoll(chatID int64, messageID int) StopPollConfig {
|
||||||
|
return StopPollConfig{
|
||||||
|
BaseEdit{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDice allows you to send a random dice roll.
|
||||||
|
func NewDice(chatID int64) DiceConfig {
|
||||||
|
return DiceConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDiceWithEmoji allows you to send a random roll of one of many types.
|
||||||
|
//
|
||||||
|
// Emoji may be 🎲 (1-6), 🎯 (1-6), or 🏀 (1-5).
|
||||||
|
func NewDiceWithEmoji(chatID int64, emoji string) DiceConfig {
|
||||||
|
return DiceConfig{
|
||||||
|
BaseChat: BaseChat{
|
||||||
|
ChatID: chatID,
|
||||||
|
},
|
||||||
|
Emoji: emoji,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeDefault represents the default scope of bot commands.
|
||||||
|
func NewBotCommandScopeDefault() BotCommandScope {
|
||||||
|
return BotCommandScope{Type: "default"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeAllPrivateChats represents the scope of bot commands,
|
||||||
|
// covering all private chats.
|
||||||
|
func NewBotCommandScopeAllPrivateChats() BotCommandScope {
|
||||||
|
return BotCommandScope{Type: "all_private_chats"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeAllGroupChats represents the scope of bot commands,
|
||||||
|
// covering all group and supergroup chats.
|
||||||
|
func NewBotCommandScopeAllGroupChats() BotCommandScope {
|
||||||
|
return BotCommandScope{Type: "all_group_chats"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeAllChatAdministrators represents the scope of bot commands,
|
||||||
|
// covering all group and supergroup chat administrators.
|
||||||
|
func NewBotCommandScopeAllChatAdministrators() BotCommandScope {
|
||||||
|
return BotCommandScope{Type: "all_chat_administrators"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeChat represents the scope of bot commands, covering a
|
||||||
|
// specific chat.
|
||||||
|
func NewBotCommandScopeChat(chatID int64) BotCommandScope {
|
||||||
|
return BotCommandScope{
|
||||||
|
Type: "chat",
|
||||||
|
ChatID: chatID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeChatAdministrators represents the scope of bot commands,
|
||||||
|
// covering all administrators of a specific group or supergroup chat.
|
||||||
|
func NewBotCommandScopeChatAdministrators(chatID int64) BotCommandScope {
|
||||||
|
return BotCommandScope{
|
||||||
|
Type: "chat_administrators",
|
||||||
|
ChatID: chatID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBotCommandScopeChatMember represents the scope of bot commands, covering a
|
||||||
|
// specific member of a group or supergroup chat.
|
||||||
|
func NewBotCommandScopeChatMember(chatID, userID int64) BotCommandScope {
|
||||||
|
return BotCommandScope{
|
||||||
|
Type: "chat_member",
|
||||||
|
ChatID: chatID,
|
||||||
|
UserID: userID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetMyCommandsWithScope allows you to set the registered commands for a
|
||||||
|
// given scope.
|
||||||
|
func NewGetMyCommandsWithScope(scope BotCommandScope) GetMyCommandsConfig {
|
||||||
|
return GetMyCommandsConfig{Scope: &scope}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetMyCommandsWithScopeAndLanguage allows you to set the registered
|
||||||
|
// commands for a given scope and language code.
|
||||||
|
func NewGetMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) GetMyCommandsConfig {
|
||||||
|
return GetMyCommandsConfig{Scope: &scope, LanguageCode: languageCode}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSetMyCommands allows you to set the registered commands.
|
||||||
|
func NewSetMyCommands(commands ...BotCommand) SetMyCommandsConfig {
|
||||||
|
return SetMyCommandsConfig{Commands: commands}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSetMyCommandsWithScope allows you to set the registered commands for a given scope.
|
||||||
|
func NewSetMyCommandsWithScope(scope BotCommandScope, commands ...BotCommand) SetMyCommandsConfig {
|
||||||
|
return SetMyCommandsConfig{Commands: commands, Scope: &scope}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSetMyCommandsWithScopeAndLanguage allows you to set the registered commands for a given scope
|
||||||
|
// and language code.
|
||||||
|
func NewSetMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string, commands ...BotCommand) SetMyCommandsConfig {
|
||||||
|
return SetMyCommandsConfig{Commands: commands, Scope: &scope, LanguageCode: languageCode}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteMyCommands allows you to delete the registered commands.
|
||||||
|
func NewDeleteMyCommands() DeleteMyCommandsConfig {
|
||||||
|
return DeleteMyCommandsConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteMyCommandsWithScope allows you to delete the registered commands for a given
|
||||||
|
// scope.
|
||||||
|
func NewDeleteMyCommandsWithScope(scope BotCommandScope) DeleteMyCommandsConfig {
|
||||||
|
return DeleteMyCommandsConfig{Scope: &scope}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDeleteMyCommandsWithScopeAndLanguage allows you to delete the registered commands for a given
|
||||||
|
// scope and language code.
|
||||||
|
func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig {
|
||||||
|
return DeleteMyCommandsConfig{Scope: &scope, LanguageCode: languageCode}
|
||||||
|
}
|
||||||
27
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/log.go
generated
vendored
Normal file
27
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/log.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
stdlog "log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BotLogger is an interface that represents the required methods to log data.
|
||||||
|
//
|
||||||
|
// Instead of requiring the standard logger, we can just specify the methods we
|
||||||
|
// use and allow users to pass anything that implements these.
|
||||||
|
type BotLogger interface {
|
||||||
|
Println(v ...interface{})
|
||||||
|
Printf(format string, v ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var log BotLogger = stdlog.New(os.Stderr, "", stdlog.LstdFlags)
|
||||||
|
|
||||||
|
// SetLogger specifies the logger that the package should use.
|
||||||
|
func SetLogger(logger BotLogger) error {
|
||||||
|
if logger == nil {
|
||||||
|
return errors.New("logger is nil")
|
||||||
|
}
|
||||||
|
log = logger
|
||||||
|
return nil
|
||||||
|
}
|
||||||
97
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/params.go
generated
vendored
Normal file
97
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/params.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Params represents a set of parameters that gets passed to a request.
|
||||||
|
type Params map[string]string
|
||||||
|
|
||||||
|
// AddNonEmpty adds a value if it not an empty string.
|
||||||
|
func (p Params) AddNonEmpty(key, value string) {
|
||||||
|
if value != "" {
|
||||||
|
p[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNonZero adds a value if it is not zero.
|
||||||
|
func (p Params) AddNonZero(key string, value int) {
|
||||||
|
if value != 0 {
|
||||||
|
p[key] = strconv.Itoa(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNonZero64 is the same as AddNonZero except uses an int64.
|
||||||
|
func (p Params) AddNonZero64(key string, value int64) {
|
||||||
|
if value != 0 {
|
||||||
|
p[key] = strconv.FormatInt(value, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddBool adds a value of a bool if it is true.
|
||||||
|
func (p Params) AddBool(key string, value bool) {
|
||||||
|
if value {
|
||||||
|
p[key] = strconv.FormatBool(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNonZeroFloat adds a floating point value that is not zero.
|
||||||
|
func (p Params) AddNonZeroFloat(key string, value float64) {
|
||||||
|
if value != 0 {
|
||||||
|
p[key] = strconv.FormatFloat(value, 'f', 6, 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddInterface adds an interface if it is not nil and can be JSON marshalled.
|
||||||
|
func (p Params) AddInterface(key string, value interface{}) error {
|
||||||
|
if value == nil || (reflect.ValueOf(value).Kind() == reflect.Ptr && reflect.ValueOf(value).IsNil()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
p[key] = string(b)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFirstValid attempts to add the first item that is not a default value.
|
||||||
|
//
|
||||||
|
// For example, AddFirstValid(0, "", "test") would add "test".
|
||||||
|
func (p Params) AddFirstValid(key string, args ...interface{}) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
switch v := arg.(type) {
|
||||||
|
case int:
|
||||||
|
if v != 0 {
|
||||||
|
p[key] = strconv.Itoa(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
if v != 0 {
|
||||||
|
p[key] = strconv.FormatInt(v, 10)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
if v != "" {
|
||||||
|
p[key] = v
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case nil:
|
||||||
|
default:
|
||||||
|
b, err := json.Marshal(arg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
p[key] = string(b)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
317
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/passport.go
generated
vendored
Normal file
317
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/passport.go
generated
vendored
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
// PassportRequestInfoConfig allows you to request passport info
|
||||||
|
type PassportRequestInfoConfig struct {
|
||||||
|
BotID int `json:"bot_id"`
|
||||||
|
Scope *PassportScope `json:"scope"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
PublicKey string `json:"public_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportScopeElement supports using one or one of several elements.
|
||||||
|
type PassportScopeElement interface {
|
||||||
|
ScopeType() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportScope is the requested scopes of data.
|
||||||
|
type PassportScope struct {
|
||||||
|
V int `json:"v"`
|
||||||
|
Data []PassportScopeElement `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportScopeElementOneOfSeveral allows you to request any one of the
|
||||||
|
// requested documents.
|
||||||
|
type PassportScopeElementOneOfSeveral struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScopeType is the scope type.
|
||||||
|
func (eo *PassportScopeElementOneOfSeveral) ScopeType() string {
|
||||||
|
return "one_of"
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportScopeElementOne requires the specified element be provided.
|
||||||
|
type PassportScopeElementOne struct {
|
||||||
|
Type string `json:"type"` // One of “personal_details”, “passport”, “driver_license”, “identity_card”, “internal_passport”, “address”, “utility_bill”, “bank_statement”, “rental_agreement”, “passport_registration”, “temporary_registration”, “phone_number”, “email”
|
||||||
|
Selfie bool `json:"selfie"`
|
||||||
|
Translation bool `json:"translation"`
|
||||||
|
NativeNames bool `json:"native_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScopeType is the scope type.
|
||||||
|
func (eo *PassportScopeElementOne) ScopeType() string {
|
||||||
|
return "one"
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
// PassportData contains information about Telegram Passport data shared with
|
||||||
|
// the bot by the user.
|
||||||
|
PassportData struct {
|
||||||
|
// Array with information about documents and other Telegram Passport
|
||||||
|
// elements that was shared with the bot
|
||||||
|
Data []EncryptedPassportElement `json:"data"`
|
||||||
|
|
||||||
|
// Encrypted credentials required to decrypt the data
|
||||||
|
Credentials *EncryptedCredentials `json:"credentials"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportFile represents a file uploaded to Telegram Passport. Currently, all
|
||||||
|
// Telegram Passport files are in JPEG format when decrypted and don't exceed
|
||||||
|
// 10MB.
|
||||||
|
PassportFile struct {
|
||||||
|
// Unique identifier for this file
|
||||||
|
FileID string `json:"file_id"`
|
||||||
|
|
||||||
|
FileUniqueID string `json:"file_unique_id"`
|
||||||
|
|
||||||
|
// File size
|
||||||
|
FileSize int `json:"file_size"`
|
||||||
|
|
||||||
|
// Unix time when the file was uploaded
|
||||||
|
FileDate int64 `json:"file_date"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptedPassportElement contains information about documents or other
|
||||||
|
// Telegram Passport elements shared with the bot by the user.
|
||||||
|
EncryptedPassportElement struct {
|
||||||
|
// Element type.
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Base64-encoded encrypted Telegram Passport element data provided by
|
||||||
|
// the user, available for "personal_details", "passport",
|
||||||
|
// "driver_license", "identity_card", "identity_passport" and "address"
|
||||||
|
// types. Can be decrypted and verified using the accompanying
|
||||||
|
// EncryptedCredentials.
|
||||||
|
Data string `json:"data,omitempty"`
|
||||||
|
|
||||||
|
// User's verified phone number, available only for "phone_number" type
|
||||||
|
PhoneNumber string `json:"phone_number,omitempty"`
|
||||||
|
|
||||||
|
// User's verified email address, available only for "email" type
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
|
||||||
|
// Array of encrypted files with documents provided by the user,
|
||||||
|
// available for "utility_bill", "bank_statement", "rental_agreement",
|
||||||
|
// "passport_registration" and "temporary_registration" types. Files can
|
||||||
|
// be decrypted and verified using the accompanying EncryptedCredentials.
|
||||||
|
Files []PassportFile `json:"files,omitempty"`
|
||||||
|
|
||||||
|
// Encrypted file with the front side of the document, provided by the
|
||||||
|
// user. Available for "passport", "driver_license", "identity_card" and
|
||||||
|
// "internal_passport". The file can be decrypted and verified using the
|
||||||
|
// accompanying EncryptedCredentials.
|
||||||
|
FrontSide *PassportFile `json:"front_side,omitempty"`
|
||||||
|
|
||||||
|
// Encrypted file with the reverse side of the document, provided by the
|
||||||
|
// user. Available for "driver_license" and "identity_card". The file can
|
||||||
|
// be decrypted and verified using the accompanying EncryptedCredentials.
|
||||||
|
ReverseSide *PassportFile `json:"reverse_side,omitempty"`
|
||||||
|
|
||||||
|
// Encrypted file with the selfie of the user holding a document,
|
||||||
|
// provided by the user; available for "passport", "driver_license",
|
||||||
|
// "identity_card" and "internal_passport". The file can be decrypted
|
||||||
|
// and verified using the accompanying EncryptedCredentials.
|
||||||
|
Selfie *PassportFile `json:"selfie,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptedCredentials contains data required for decrypting and
|
||||||
|
// authenticating EncryptedPassportElement. See the Telegram Passport
|
||||||
|
// Documentation for a complete description of the data decryption and
|
||||||
|
// authentication processes.
|
||||||
|
EncryptedCredentials struct {
|
||||||
|
// Base64-encoded encrypted JSON-serialized data with unique user's
|
||||||
|
// payload, data hashes and secrets required for EncryptedPassportElement
|
||||||
|
// decryption and authentication
|
||||||
|
Data string `json:"data"`
|
||||||
|
|
||||||
|
// Base64-encoded data hash for data authentication
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
|
||||||
|
// Base64-encoded secret, encrypted with the bot's public RSA key,
|
||||||
|
// required for data decryption
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementError represents an error in the Telegram Passport element
|
||||||
|
// which was submitted that should be resolved by the user.
|
||||||
|
PassportElementError interface{}
|
||||||
|
|
||||||
|
// PassportElementErrorDataField represents an issue in one of the data
|
||||||
|
// fields that was provided by the user. The error is considered resolved
|
||||||
|
// when the field's value changes.
|
||||||
|
PassportElementErrorDataField struct {
|
||||||
|
// Error source, must be data
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the error, one
|
||||||
|
// of "personal_details", "passport", "driver_license", "identity_card",
|
||||||
|
// "internal_passport", "address"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Name of the data field which has the error
|
||||||
|
FieldName string `json:"field_name"`
|
||||||
|
|
||||||
|
// Base64-encoded data hash
|
||||||
|
DataHash string `json:"data_hash"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementErrorFrontSide represents an issue with the front side of
|
||||||
|
// a document. The error is considered resolved when the file with the front
|
||||||
|
// side of the document changes.
|
||||||
|
PassportElementErrorFrontSide struct {
|
||||||
|
// Error source, must be front_side
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the issue, one
|
||||||
|
// of "passport", "driver_license", "identity_card", "internal_passport"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Base64-encoded hash of the file with the front side of the document
|
||||||
|
FileHash string `json:"file_hash"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementErrorReverseSide represents an issue with the reverse side
|
||||||
|
// of a document. The error is considered resolved when the file with reverse
|
||||||
|
// side of the document changes.
|
||||||
|
PassportElementErrorReverseSide struct {
|
||||||
|
// Error source, must be reverse_side
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the issue, one
|
||||||
|
// of "driver_license", "identity_card"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Base64-encoded hash of the file with the reverse side of the document
|
||||||
|
FileHash string `json:"file_hash"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementErrorSelfie represents an issue with the selfie with a
|
||||||
|
// document. The error is considered resolved when the file with the selfie
|
||||||
|
// changes.
|
||||||
|
PassportElementErrorSelfie struct {
|
||||||
|
// Error source, must be selfie
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the issue, one
|
||||||
|
// of "passport", "driver_license", "identity_card", "internal_passport"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Base64-encoded hash of the file with the selfie
|
||||||
|
FileHash string `json:"file_hash"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementErrorFile represents an issue with a document scan. The
|
||||||
|
// error is considered resolved when the file with the document scan changes.
|
||||||
|
PassportElementErrorFile struct {
|
||||||
|
// Error source, must be a file
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the issue, one
|
||||||
|
// of "utility_bill", "bank_statement", "rental_agreement",
|
||||||
|
// "passport_registration", "temporary_registration"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// Base64-encoded file hash
|
||||||
|
FileHash string `json:"file_hash"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PassportElementErrorFiles represents an issue with a list of scans. The
|
||||||
|
// error is considered resolved when the list of files containing the scans
|
||||||
|
// changes.
|
||||||
|
PassportElementErrorFiles struct {
|
||||||
|
// Error source, must be files
|
||||||
|
Source string `json:"source"`
|
||||||
|
|
||||||
|
// The section of the user's Telegram Passport which has the issue, one
|
||||||
|
// of "utility_bill", "bank_statement", "rental_agreement",
|
||||||
|
// "passport_registration", "temporary_registration"
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
// List of base64-encoded file hashes
|
||||||
|
FileHashes []string `json:"file_hashes"`
|
||||||
|
|
||||||
|
// Error message
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Credentials contains encrypted data.
|
||||||
|
Credentials struct {
|
||||||
|
Data SecureData `json:"secure_data"`
|
||||||
|
// Nonce the same nonce given in the request
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecureData is a map of the fields and their encrypted values.
|
||||||
|
SecureData map[string]*SecureValue
|
||||||
|
// PersonalDetails *SecureValue `json:"personal_details"`
|
||||||
|
// Passport *SecureValue `json:"passport"`
|
||||||
|
// InternalPassport *SecureValue `json:"internal_passport"`
|
||||||
|
// DriverLicense *SecureValue `json:"driver_license"`
|
||||||
|
// IdentityCard *SecureValue `json:"identity_card"`
|
||||||
|
// Address *SecureValue `json:"address"`
|
||||||
|
// UtilityBill *SecureValue `json:"utility_bill"`
|
||||||
|
// BankStatement *SecureValue `json:"bank_statement"`
|
||||||
|
// RentalAgreement *SecureValue `json:"rental_agreement"`
|
||||||
|
// PassportRegistration *SecureValue `json:"passport_registration"`
|
||||||
|
// TemporaryRegistration *SecureValue `json:"temporary_registration"`
|
||||||
|
|
||||||
|
// SecureValue contains encrypted values for a SecureData item.
|
||||||
|
SecureValue struct {
|
||||||
|
Data *DataCredentials `json:"data"`
|
||||||
|
FrontSide *FileCredentials `json:"front_side"`
|
||||||
|
ReverseSide *FileCredentials `json:"reverse_side"`
|
||||||
|
Selfie *FileCredentials `json:"selfie"`
|
||||||
|
Translation []*FileCredentials `json:"translation"`
|
||||||
|
Files []*FileCredentials `json:"files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataCredentials contains information required to decrypt data.
|
||||||
|
DataCredentials struct {
|
||||||
|
// DataHash checksum of encrypted data
|
||||||
|
DataHash string `json:"data_hash"`
|
||||||
|
// Secret of encrypted data
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileCredentials contains information required to decrypt files.
|
||||||
|
FileCredentials struct {
|
||||||
|
// FileHash checksum of encrypted data
|
||||||
|
FileHash string `json:"file_hash"`
|
||||||
|
// Secret of encrypted data
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersonalDetails https://core.telegram.org/passport#personaldetails
|
||||||
|
PersonalDetails struct {
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
MiddleName string `json:"middle_name"`
|
||||||
|
BirthDate string `json:"birth_date"`
|
||||||
|
Gender string `json:"gender"`
|
||||||
|
CountryCode string `json:"country_code"`
|
||||||
|
ResidenceCountryCode string `json:"residence_country_code"`
|
||||||
|
FirstNameNative string `json:"first_name_native"`
|
||||||
|
LastNameNative string `json:"last_name_native"`
|
||||||
|
MiddleNameNative string `json:"middle_name_native"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDDocumentData https://core.telegram.org/passport#iddocumentdata
|
||||||
|
IDDocumentData struct {
|
||||||
|
DocumentNumber string `json:"document_no"`
|
||||||
|
ExpiryDate string `json:"expiry_date"`
|
||||||
|
}
|
||||||
|
)
|
||||||
3225
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/types.go
generated
vendored
Normal file
3225
vendor/github.com/go-telegram-bot-api/telegram-bot-api/v5/types.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@@ -162,6 +162,9 @@ github.com/go-ini/ini
|
|||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/go-ozzo/ozzo-validation/v4
|
github.com/go-ozzo/ozzo-validation/v4
|
||||||
github.com/go-ozzo/ozzo-validation/v4/is
|
github.com/go-ozzo/ozzo-validation/v4/is
|
||||||
|
# github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
|
## explicit; go 1.16
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5
|
||||||
# github.com/go-test/deep v1.1.0
|
# github.com/go-test/deep v1.1.0
|
||||||
## explicit; go 1.16
|
## explicit; go 1.16
|
||||||
# github.com/goccy/go-json v0.10.3
|
# github.com/goccy/go-json v0.10.3
|
||||||
|
|||||||
Reference in New Issue
Block a user