🔀 Merge branch 'feature/refactor' into develop
This commit is contained in:
commit
b9272596e9
|
@ -22,3 +22,6 @@ _testmain.go
|
||||||
*.exe
|
*.exe
|
||||||
*.test
|
*.test
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
|
ffjson-inception*
|
||||||
|
*_ffjson_expose.go
|
|
@ -1,13 +1,5 @@
|
||||||
image: golang:alpine
|
image: golang:alpine
|
||||||
|
|
||||||
cache:
|
|
||||||
paths:
|
|
||||||
- /go/src/github.com
|
|
||||||
- /go/src/gitlab.com
|
|
||||||
- /go/src/golang.org
|
|
||||||
- /go/src/google.golang.org
|
|
||||||
- /go/src/gopkg.in
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- review
|
- review
|
||||||
|
@ -26,11 +18,6 @@ unit_tests:
|
||||||
script:
|
script:
|
||||||
- make test
|
- make test
|
||||||
|
|
||||||
.race_detector:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- make race
|
|
||||||
|
|
||||||
code_coverage:
|
code_coverage:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
19
Makefile
19
Makefile
|
@ -1,32 +1,29 @@
|
||||||
PROJECT_NAMESPACE := $(CI_PROJECT_NAMESPACE)
|
PROJECT_NAMESPACE := $(CI_PROJECT_NAMESPACE)
|
||||||
PROJECT_NAME := $(CI_PROJECT_NAME)
|
PROJECT_NAME := $(CI_PROJECT_NAME)
|
||||||
PROJECT_PATH := $(PROJECT_NAMESPACE)/$(PROJECT_NAME)
|
PROJECT_PATH := "$(PROJECT_NAMESPACE)/$(PROJECT_NAME)"
|
||||||
PACKAGE_NAME := "gitlab.com/$(PROJECT_PATH)"
|
PACKAGE_NAME := "gitlab.com/$(PROJECT_PATH)"
|
||||||
PACKAGE_PATH := $(GOPATH)/src/$(PACKAGE_NAME)
|
PACKAGE_PATH := "$(GOPATH)/src/$(PACKAGE_NAME)"
|
||||||
PACKAGE_LIST := $(shell go list $(PACKAGE_NAME)/... | grep -v /vendor/)
|
PACKAGE_LIST := $(shell go list $(PACKAGE_NAME)/... | grep -v /vendor/)
|
||||||
GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go)
|
GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go)
|
||||||
|
|
||||||
.PHONY: all lint test rase coverage dep build clean
|
.PHONY: all lint test rase coverage dep
|
||||||
|
|
||||||
all: build
|
all: dep test race lint
|
||||||
|
|
||||||
lint: ## Lint the files
|
lint: ## Lint the files
|
||||||
@golangci-lint run
|
@golangci-lint run ./...
|
||||||
|
|
||||||
test: ## Run unittests
|
test: ## Run unittests
|
||||||
@go test -short ${PACKAGE_LIST}
|
@go test -short $(PACKAGE_NAME)/...
|
||||||
|
|
||||||
race: dep ## Run data race detector
|
race: dep ## Run data race detector
|
||||||
@go test -race -short ${PACKAGE_LIST}
|
@go test -race -short ${PACKAGE_LIST}
|
||||||
|
|
||||||
coverage: ## Generate global code coverage report
|
coverage: ## Generate global code coverage report
|
||||||
@go test -cover -v -coverpkg=$(PACKAGE_NAME) ${PACKAGE_LIST}
|
@go test -cover -v -coverpkg=$(PACKAGE_NAME)/... ${PACKAGE_LIST}
|
||||||
|
|
||||||
dep: ## Get the dependencies
|
dep: ## Get the dependencies
|
||||||
@go get -v -d -t ${PACKAGE_LIST}
|
@go get -v -d -t $(PACKAGE_NAME)/...
|
||||||
|
|
||||||
clean: ## Remove previous build
|
|
||||||
@rm -f $(PROJECT_NAME)
|
|
||||||
|
|
||||||
help: ## Display this help screen
|
help: ## Display this help screen
|
||||||
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
I develop this project in my spare time, and I do it and I will do it free of charge. However, you can make a donation or become a sponsor to make sure that I have enough coffee and pizza for night coding.
|
I develop this project in my spare time, and I do it and I will do it free of charge. However, you can make a donation or become a sponsor to make sure that I have enough coffee and pizza for night coding.
|
||||||
|
|
||||||
**These people sponsored current version of the project:**
|
**These people sponsored current version of the project:**
|
||||||
- Alina
|
|
||||||
- Aurielb
|
- Aurielb
|
||||||
- @kirillDanshin
|
|
||||||
- MoD21k
|
- MoD21k
|
||||||
- Yami Odymel
|
- @YamiOdymel
|
|
@ -0,0 +1,56 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddStickerToSetParameters struct {
|
||||||
|
// User identifier of sticker set owner
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// Sticker set name
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. More info on Sending Files »
|
||||||
|
PNGSticker interface{} `json:"png_sticker"`
|
||||||
|
|
||||||
|
// One or more emoji corresponding to the sticker
|
||||||
|
Emojis string `json:"emojis"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for position where the mask should be placed on faces
|
||||||
|
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddStickerToSet add a new sticker to a set created by the bot. Returns True
|
||||||
|
// on success.
|
||||||
|
func (b *Bot) AddStickerToSet(params *AddStickerToSetParameters) (bool, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.SetUint("user_id", params.UserID)
|
||||||
|
|
||||||
|
if !strings.HasSuffix(strings.ToLower(params.Name), strings.ToLower("_by_"+b.Username)) {
|
||||||
|
params.Name = params.Name + "_by_" + b.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Set("emojis", params.Emojis)
|
||||||
|
|
||||||
|
if params.MaskPosition != nil {
|
||||||
|
mp, err := parser.Marshal(params.MaskPosition)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
args.SetBytesV("mask_position", mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.Upload(MethodAddStickerToSet, TypeSticker, "sticker", params.PNGSticker, args)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
type (
|
||||||
|
// AnswerCallbackQueryParameters represents data for AnswerCallbackQuery method.
|
||||||
|
AnswerCallbackQueryParameters struct {
|
||||||
|
// Unique identifier for the query to be answered
|
||||||
|
CallbackQueryID string `json:"callback_query_id"`
|
||||||
|
|
||||||
|
// Text of the notification. If not specified, nothing will be shown to the
|
||||||
|
// user, 0-200 characters
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
|
||||||
|
// URL that will be opened by the user's client. If you have created a Game
|
||||||
|
// and accepted the conditions via @Botfather, specify the URL that opens
|
||||||
|
// your game – note that this will only work if the query comes from a
|
||||||
|
// callback_game button.
|
||||||
|
//
|
||||||
|
// Otherwise, you may use links like t.me/your_bot?start=XXXX that open your
|
||||||
|
// bot with a parameter.
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
|
||||||
|
// If true, an alert will be shown by the client instead of a notification at
|
||||||
|
// the top of the chat screen. Defaults to false.
|
||||||
|
ShowAlert bool `json:"show_alert,omitempty"`
|
||||||
|
|
||||||
|
// The maximum amount of time in seconds that the result of the callback
|
||||||
|
// query may be cached client-side. Telegram apps will support caching
|
||||||
|
// starting in version 3.14. Defaults to 0.
|
||||||
|
CacheTime int `json:"cache_time,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerPreCheckoutQueryParameters represents data for AnswerPreCheckoutQuery
|
||||||
|
// method.
|
||||||
|
AnswerPreCheckoutQueryParameters struct {
|
||||||
|
// Unique identifier for the query to be answered
|
||||||
|
PreCheckoutQueryID string `json:"pre_checkout_query_id"`
|
||||||
|
|
||||||
|
// Required if ok is False. Error message in human readable form that
|
||||||
|
// explains the reason for failure to proceed with the checkout (e.g. "Sorry,
|
||||||
|
// somebody just bought the last of our amazing black T-shirts while you were
|
||||||
|
// busy filling out your payment details. Please choose a different color or
|
||||||
|
// garment!"). Telegram will display this message to the user.
|
||||||
|
ErrorMessage string `json:"error_message,omitempty"`
|
||||||
|
|
||||||
|
// Specify True if everything is alright (goods are available, etc.) and the
|
||||||
|
// bot is ready to proceed with the order. Use False if there are any
|
||||||
|
// problems.
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerShippingQueryParameters represents data for AnswerShippingQuery method.
|
||||||
|
AnswerShippingQueryParameters struct {
|
||||||
|
// Unique identifier for the query to be answered
|
||||||
|
ShippingQueryID string `json:"shipping_query_id"`
|
||||||
|
|
||||||
|
// Required if ok is False. Error message in human readable form that
|
||||||
|
// explains why it is impossible to complete the order (e.g. "Sorry, delivery
|
||||||
|
// to your desired address is unavailable'). Telegram will display this
|
||||||
|
// message to the user.
|
||||||
|
ErrorMessage string `json:"error_message,omitempty"`
|
||||||
|
|
||||||
|
// Specify True if delivery to the specified address is possible and False
|
||||||
|
// if there are any problems (for example, if delivery to the specified
|
||||||
|
// address is not possible)
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
|
||||||
|
// Required if ok is True. A JSON-serialized array of available shipping
|
||||||
|
// options.
|
||||||
|
ShippingOptions []ShippingOption `json:"shipping_options,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerInlineQueryParameters represents data for AnswerInlineQuery method.
|
||||||
|
AnswerInlineQueryParameters struct {
|
||||||
|
// Unique identifier for the answered query
|
||||||
|
InlineQueryID string `json:"inline_query_id"`
|
||||||
|
|
||||||
|
// Pass the offset that a client should send in the next query with the same
|
||||||
|
// text to receive more results. Pass an empty string if there are no more
|
||||||
|
// results or if you don‘t support pagination. Offset length can’t exceed 64
|
||||||
|
// bytes.
|
||||||
|
NextOffset string `json:"next_offset,omitempty"`
|
||||||
|
|
||||||
|
// If passed, clients will display a button with specified text that switches
|
||||||
|
// the user to a private chat with the bot and sends the bot a start message
|
||||||
|
// with the parameter switch_pm_parameter
|
||||||
|
SwitchPrivateMessageText string `json:"switch_pm_text,omitempty"`
|
||||||
|
|
||||||
|
// Deep-linking parameter for the /start message sent to the bot when user
|
||||||
|
// presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and -
|
||||||
|
// are allowed.
|
||||||
|
SwitchPrivateMessageParameter string `json:"switch_pm_parameter,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized array of results for the inline query
|
||||||
|
Results []interface{} `json:"results"`
|
||||||
|
|
||||||
|
// The maximum amount of time in seconds that the result of the inline query
|
||||||
|
// may be cached on the server. Defaults to 300.
|
||||||
|
CacheTime int `json:"cache_time,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if results may be cached on the server side only for the user
|
||||||
|
// that sent the query. By default, results may be returned to any user who
|
||||||
|
// sends the same query
|
||||||
|
IsPersonal bool `json:"is_personal,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewAnswerCallbackQuery creates AnswerCallbackQueryParameters only with
|
||||||
|
// required parameters.
|
||||||
|
func NewAnswerCallbackQuery(callbackQueryID string) *AnswerCallbackQueryParameters {
|
||||||
|
return &AnswerCallbackQueryParameters{CallbackQueryID: callbackQueryID}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnswerPreCheckoutQuery creates AnswerPreCheckoutQueryParameters only with
|
||||||
|
// required parameters.
|
||||||
|
func NewAnswerPreCheckoutQuery(preCheckoutQueryID string, ok bool) *AnswerPreCheckoutQueryParameters {
|
||||||
|
return &AnswerPreCheckoutQueryParameters{
|
||||||
|
PreCheckoutQueryID: preCheckoutQueryID,
|
||||||
|
Ok: ok,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnswerShippingQuery creates AnswerShippingQueryParameters only with
|
||||||
|
// required parameters.
|
||||||
|
func NewAnswerShippingQuery(shippingQueryID string, ok bool) *AnswerShippingQueryParameters {
|
||||||
|
return &AnswerShippingQueryParameters{
|
||||||
|
ShippingQueryID: shippingQueryID,
|
||||||
|
Ok: ok,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnswerInlineQuery creates AnswerInlineQueryParameters only with required
|
||||||
|
// parameters.
|
||||||
|
func NewAnswerInlineQuery(inlineQueryID string, results ...interface{}) *AnswerInlineQueryParameters {
|
||||||
|
return &AnswerInlineQueryParameters{
|
||||||
|
InlineQueryID: inlineQueryID,
|
||||||
|
Results: results,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerCallbackQuery send answers to callback queries sent from inline
|
||||||
|
// keyboards. The answer will be displayed to the user as a notification at the
|
||||||
|
// top of the chat screen or as an alert. On success, True is returned.
|
||||||
|
//
|
||||||
|
// Alternatively, the user can be redirected to the specified Game URL. For this
|
||||||
|
// option to work, you must first create a game for your bot via @Botfather and
|
||||||
|
// accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX
|
||||||
|
// that open your bot with a parameter.
|
||||||
|
func (bot *Bot) AnswerCallbackQuery(params *AnswerCallbackQueryParameters) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodAnswerCallbackQuery)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerPreCheckoutQuery respond to such pre-checkout queries.
|
||||||
|
//
|
||||||
|
// Once the user has confirmed their payment and shipping details, the Bot API
|
||||||
|
// sends the final confirmation in the form of an Update with the field
|
||||||
|
// pre_checkout_query. Use this method to respond to such pre-checkout queries.
|
||||||
|
// On success, True is returned.
|
||||||
|
//
|
||||||
|
// Note: The Bot API must receive an answer within 10 seconds after the
|
||||||
|
// pre-checkout query was sent.
|
||||||
|
func (bot *Bot) AnswerPreCheckoutQuery(params *AnswerShippingQueryParameters) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodAnswerPreCheckoutQuery)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerShippingQuery reply to shipping queries.
|
||||||
|
//
|
||||||
|
// If you sent an invoice requesting a shipping address and the parameter
|
||||||
|
// is_flexible was specified, the Bot API will send an Update with a
|
||||||
|
// shipping_query field to the bot. On success, True is returned.
|
||||||
|
func (bot *Bot) AnswerShippingQuery(params *AnswerShippingQueryParameters) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodAnswerShippingQuery)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnswerInlineQuery send answers to an inline query. On success, True is returned.
|
||||||
|
//
|
||||||
|
// No more than 50 results per query are allowed.
|
||||||
|
func (bot *Bot) AnswerInlineQuery(params *AnswerInlineQueryParameters) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodAnswerInlineQuery)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
|
@ -1,60 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// AnswerCallbackQueryParameters represents data for AnswerCallbackQuery method.
|
|
||||||
type AnswerCallbackQueryParameters struct {
|
|
||||||
// Unique identifier for the query to be answered
|
|
||||||
CallbackQueryID string `json:"callback_query_id"`
|
|
||||||
|
|
||||||
// Text of the notification. If not specified, nothing will be shown to the
|
|
||||||
// user, 0-200 characters
|
|
||||||
Text string `json:"text,omitempty"`
|
|
||||||
|
|
||||||
// URL that will be opened by the user's client. If you have created a Game
|
|
||||||
// and accepted the conditions via @Botfather, specify the URL that opens
|
|
||||||
// your game – note that this will only work if the query comes from a
|
|
||||||
// callback_game button.
|
|
||||||
//
|
|
||||||
// Otherwise, you may use links like t.me/your_bot?start=XXXX that open your
|
|
||||||
// bot with a parameter.
|
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
|
|
||||||
// If true, an alert will be shown by the client instead of a notification at
|
|
||||||
// the top of the chat screen. Defaults to false.
|
|
||||||
ShowAlert bool `json:"show_alert,omitempty"`
|
|
||||||
|
|
||||||
// The maximum amount of time in seconds that the result of the callback
|
|
||||||
// query may be cached client-side. Telegram apps will support caching
|
|
||||||
// starting in version 3.14. Defaults to 0.
|
|
||||||
CacheTime int `json:"cache_time,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAnswerCallbackQuery creates AnswerCallbackQueryParameters only with
|
|
||||||
// required parameters.
|
|
||||||
func NewAnswerCallbackQuery(callbackQueryID string) *AnswerCallbackQueryParameters {
|
|
||||||
return &AnswerCallbackQueryParameters{CallbackQueryID: callbackQueryID}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnswerCallbackQuery send answers to callback queries sent from inline
|
|
||||||
// keyboards. The answer will be displayed to the user as a notification at the
|
|
||||||
// top of the chat screen or as an alert. On success, True is returned.
|
|
||||||
//
|
|
||||||
// Alternatively, the user can be redirected to the specified Game URL. For this
|
|
||||||
// option to work, you must first create a game for your bot via @Botfather and
|
|
||||||
// accept the terms. Otherwise, you may use links like t.me/your_bot?start=XXXX
|
|
||||||
// that open your bot with a parameter.
|
|
||||||
func (bot *Bot) AnswerCallbackQuery(params *AnswerCallbackQueryParameters) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodAnswerCallbackQuery)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// AnswerPreCheckoutQueryParameters represents data for AnswerPreCheckoutQuery
|
|
||||||
// method.
|
|
||||||
type AnswerPreCheckoutQueryParameters struct {
|
|
||||||
// Unique identifier for the query to be answered
|
|
||||||
PreCheckoutQueryID string `json:"pre_checkout_query_id"`
|
|
||||||
|
|
||||||
// Required if ok is False. Error message in human readable form that
|
|
||||||
// explains the reason for failure to proceed with the checkout (e.g. "Sorry,
|
|
||||||
// somebody just bought the last of our amazing black T-shirts while you were
|
|
||||||
// busy filling out your payment details. Please choose a different color or
|
|
||||||
// garment!"). Telegram will display this message to the user.
|
|
||||||
ErrorMessage string `json:"error_message,omitempty"`
|
|
||||||
|
|
||||||
// Specify True if everything is alright (goods are available, etc.) and the
|
|
||||||
// bot is ready to proceed with the order. Use False if there are any
|
|
||||||
// problems.
|
|
||||||
Ok bool `json:"ok"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAnswerPreCheckoutQuery creates AnswerPreCheckoutQueryParameters only with
|
|
||||||
// required parameters.
|
|
||||||
func NewAnswerPreCheckoutQuery(preCheckoutQueryID string, ok bool) *AnswerPreCheckoutQueryParameters {
|
|
||||||
return &AnswerPreCheckoutQueryParameters{
|
|
||||||
PreCheckoutQueryID: preCheckoutQueryID,
|
|
||||||
Ok: ok,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnswerPreCheckoutQuery respond to such pre-checkout queries.
|
|
||||||
//
|
|
||||||
// Once the user has confirmed their payment and shipping details, the Bot API
|
|
||||||
// sends the final confirmation in the form of an Update with the field
|
|
||||||
// pre_checkout_query. Use this method to respond to such pre-checkout queries.
|
|
||||||
// On success, True is returned.
|
|
||||||
//
|
|
||||||
// Note: The Bot API must receive an answer within 10 seconds after the
|
|
||||||
// pre-checkout query was sent.
|
|
||||||
func (bot *Bot) AnswerPreCheckoutQuery(params *AnswerShippingQueryParameters) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodAnswerPreCheckoutQuery)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// AnswerShippingQueryParameters represents data for AnswerShippingQuery method.
|
|
||||||
type AnswerShippingQueryParameters struct {
|
|
||||||
// Unique identifier for the query to be answered
|
|
||||||
ShippingQueryID string `json:"shipping_query_id"`
|
|
||||||
|
|
||||||
// Required if ok is False. Error message in human readable form that
|
|
||||||
// explains why it is impossible to complete the order (e.g. "Sorry, delivery
|
|
||||||
// to your desired address is unavailable'). Telegram will display this
|
|
||||||
// message to the user.
|
|
||||||
ErrorMessage string `json:"error_message,omitempty"`
|
|
||||||
|
|
||||||
// Specify True if delivery to the specified address is possible and False
|
|
||||||
// if there are any problems (for example, if delivery to the specified
|
|
||||||
// address is not possible)
|
|
||||||
Ok bool `json:"ok"`
|
|
||||||
|
|
||||||
// Required if ok is True. A JSON-serialized array of available shipping
|
|
||||||
// options.
|
|
||||||
ShippingOptions []ShippingOption `json:"shipping_options,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAnswerShippingQuery creates AnswerShippingQueryParameters only with
|
|
||||||
// required parameters.
|
|
||||||
func NewAnswerShippingQuery(shippingQueryID string, ok bool) *AnswerShippingQueryParameters {
|
|
||||||
return &AnswerShippingQueryParameters{
|
|
||||||
ShippingQueryID: shippingQueryID,
|
|
||||||
Ok: ok,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnswerShippingQuery reply to shipping queries.
|
|
||||||
//
|
|
||||||
// If you sent an invoice requesting a shipping address and the parameter
|
|
||||||
// is_flexible was specified, the Bot API will send an Update with a
|
|
||||||
// shipping_query field to the bot. On success, True is returned.
|
|
||||||
func (bot *Bot) AnswerShippingQuery(params *AnswerShippingQueryParameters) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodAnswerShippingQuery)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
2
const.go
2
const.go
|
@ -1,7 +1,7 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
// Version represents current version of Telegram API supported by this package
|
// Version represents current version of Telegram API supported by this package
|
||||||
const Version = 4.0
|
const Version = "4.3"
|
||||||
|
|
||||||
// Action represents available and supported status actions of bot
|
// Action represents available and supported status actions of bot
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateNewStickerSetParameters struct {
|
||||||
|
// User identifier of created sticker set owner
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// Short name of sticker set, to be used in t.me/addstickers/ URLs
|
||||||
|
// (e.g., animals). Can contain only english letters, digits and
|
||||||
|
// underscores. Must begin with a letter, can't contain consecutive
|
||||||
|
// underscores and must end in “_by_<bot username>”. <bot_username>
|
||||||
|
// is case insensitive. 1-64 characters.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Sticker set title, 1-64 characters
|
||||||
|
Title string `json:"title"`
|
||||||
|
|
||||||
|
// Png image with the sticker, must be up to 512 kilobytes in size,
|
||||||
|
// dimensions must not exceed 512px, and either width or height must
|
||||||
|
// be exactly 512px. Pass a file_id as a String to send a file that
|
||||||
|
// already exists on the Telegram servers, pass an HTTP URL as a
|
||||||
|
// String for Telegram to get a file from the Internet, or upload
|
||||||
|
// a new one using multipart/form-data.
|
||||||
|
PNGSticker interface{} `json:"png_sticker"`
|
||||||
|
|
||||||
|
// One or more emoji corresponding to the sticker
|
||||||
|
Emojis string `json:"emojis"`
|
||||||
|
|
||||||
|
// Pass True, if a set of mask stickers should be created
|
||||||
|
ContainsMasks bool `json:"contains_masks,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for position where the mask should be
|
||||||
|
// placed on faces
|
||||||
|
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNewStickerSet create new sticker set owned by a user. The bot will be
|
||||||
|
// able to edit the created sticker set. Returns True on success.
|
||||||
|
func (b *Bot) CreateNewStickerSet(params *CreateNewStickerSetParameters) (bool, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.SetUint("user_id", params.UserID)
|
||||||
|
|
||||||
|
if !strings.HasSuffix(strings.ToLower(params.Name), strings.ToLower("_by_"+b.Username)) {
|
||||||
|
params.Name = params.Name + "_by_" + b.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Set("name", params.Name)
|
||||||
|
args.Set("title", params.Title)
|
||||||
|
args.Set("emojis", params.Emojis)
|
||||||
|
args.Set("contains_masks", strconv.FormatBool(params.ContainsMasks))
|
||||||
|
|
||||||
|
if params.MaskPosition != nil {
|
||||||
|
mp, err := parser.Marshal(params.MaskPosition)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
args.SetBytesV("mask_position", mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.Upload(MethodCreateNewStickerSet, TypeSticker, "sticker", params.PNGSticker, args)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
type (
|
||||||
|
// DeleteChatPhotoParameters represents data for DeleteChatPhoto method.
|
||||||
|
DeleteChatPhotoParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteChatStickerSetParameters represents data for DeleteChatStickerSet method.
|
||||||
|
DeleteChatStickerSetParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMessageParameters represents data for DeleteMessage method.
|
||||||
|
DeleteMessageParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Identifier of the message to delete
|
||||||
|
MessageID int `json:"message_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStickerFromSetParameters represents data for DeleteStickerFromSet method.
|
||||||
|
DeleteStickerFromSetParameters struct {
|
||||||
|
// File identifier of the sticker
|
||||||
|
Sticker string `json:"sticker"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteChatPhoto delete a chat photo. Photos can't be changed for private
|
||||||
|
// chats. The bot must be an administrator in the chat for this to work and must
|
||||||
|
// have the appropriate admin rights. Returns True on success.
|
||||||
|
//
|
||||||
|
// Note: In regular groups (non-supergroups), this method will only work if the
|
||||||
|
// 'All Members Are Admins' setting is off in the target group.
|
||||||
|
func (bot *Bot) DeleteChatPhoto(chatID int64) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&DeleteChatPhotoParameters{ChatID: chatID})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodDeleteChatPhoto)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteChatStickerSet delete a group sticker set from a supergroup. The bot must be an administrator
|
||||||
|
// in the chat for this to work and must have the appropriate admin rights. Use the field
|
||||||
|
// can_set_sticker_set optionally returned in getChat requests to check if the bot can use this
|
||||||
|
// method. Returns True on success.
|
||||||
|
func (bot *Bot) DeleteChatStickerSet(chatID int64) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&DeleteChatStickerSetParameters{ChatID: chatID})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodDeleteChatStickerSet)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteWebhook remove webhook integration if you decide to switch back to
|
||||||
|
// getUpdates. Returns True on success. Requires no parameters.
|
||||||
|
func (bot *Bot) DeleteWebhook() (bool, error) {
|
||||||
|
resp, err := bot.request(nil, MethodDeleteWebhook)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMessage delete a message, including service messages, with the following
|
||||||
|
// limitations: A message can only be deleted if it was sent less than 48 hours
|
||||||
|
// ago; Bots can delete outgoing messages in groups and supergroups; Bots granted
|
||||||
|
// can_post_messages permissions can delete outgoing messages in channels; If the
|
||||||
|
// bot is an administrator of a group, it can delete any message there; If the
|
||||||
|
// bot has can_delete_messages permission in a supergroup or a channel, it can
|
||||||
|
// delete any message there. Returns True on success.
|
||||||
|
func (bot *Bot) DeleteMessage(chatID int64, messageID int) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&DeleteMessageParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: messageID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodDeleteMessage)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteStickerFromSet delete a sticker from a set created by the bot. Returns
|
||||||
|
// True on success.
|
||||||
|
func (bot *Bot) DeleteStickerFromSet(sticker string) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&DeleteStickerFromSetParameters{Sticker: sticker})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodDeleteStickerFromSet)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// DeleteChatPhotoParameters represents data for DeleteChatPhoto method.
|
|
||||||
type DeleteChatPhotoParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteChatPhoto delete a chat photo. Photos can't be changed for private
|
|
||||||
// chats. The bot must be an administrator in the chat for this to work and must
|
|
||||||
// have the appropriate admin rights. Returns True on success.
|
|
||||||
//
|
|
||||||
// Note: In regular groups (non-supergroups), this method will only work if the
|
|
||||||
// 'All Members Are Admins' setting is off in the target group.
|
|
||||||
func (bot *Bot) DeleteChatPhoto(chatID int64) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&DeleteChatPhotoParameters{ChatID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodDeleteChatPhoto)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// DeleteChatStickerSetParameters represents data for DeleteChatStickerSet method.
|
|
||||||
type DeleteChatStickerSetParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteChatStickerSet delete a group sticker set from a supergroup. The bot must be an administrator
|
|
||||||
// in the chat for this to work and must have the appropriate admin rights. Use the field
|
|
||||||
// can_set_sticker_set optionally returned in getChat requests to check if the bot can use this
|
|
||||||
// method. Returns True on success.
|
|
||||||
func (bot *Bot) DeleteChatStickerSet(chatID int64) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&DeleteChatStickerSetParameters{ChatID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodDeleteChatStickerSet)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// DeleteWebhook remove webhook integration if you decide to switch back to
|
|
||||||
// getUpdates. Returns True on success. Requires no parameters.
|
|
||||||
func (bot *Bot) DeleteWebhook() (ok bool, err error) {
|
|
||||||
resp, err := bot.request(nil, MethodDeleteWebhook)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,8 +1,32 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
// EditMessageLiveLocationParameters represents data for EditMessageLiveLocation
|
||||||
|
// method.
|
||||||
|
EditMessageLiveLocationParameters struct {
|
||||||
|
// Required if inline_message_id is not specified. Unique identifier for the
|
||||||
|
// target chat or username of the target channel (in the format
|
||||||
|
// @channelusername)
|
||||||
|
ChatID int64 `json:"chat_id,omitempty"`
|
||||||
|
|
||||||
|
// Required if inline_message_id is not specified. Identifier of the sent
|
||||||
|
// message
|
||||||
|
MessageID int `json:"message_id,omitempty"`
|
||||||
|
|
||||||
|
// Required if chat_id and message_id are not specified. Identifier of the
|
||||||
|
// inline message
|
||||||
|
InlineMessageID string `json:"inline_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Latitude of new location
|
||||||
|
Latitude float32 `json:"latitude"`
|
||||||
|
|
||||||
|
// Longitude of new location
|
||||||
|
Longitude float32 `json:"longitude"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for a new inline keyboard.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// EditMessageTextParameters represents data for EditMessageText method.
|
// EditMessageTextParameters represents data for EditMessageText method.
|
||||||
EditMessageTextParameters struct {
|
EditMessageTextParameters struct {
|
||||||
// Required if inline_message_id is not specified. Unique identifier for the
|
// Required if inline_message_id is not specified. Unique identifier for the
|
||||||
|
@ -94,17 +118,17 @@ type (
|
||||||
// A JSON-serialized object for an inline keyboard.
|
// A JSON-serialized object for an inline keyboard.
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMessageParameters represents data for DeleteMessage method.
|
|
||||||
DeleteMessageParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Identifier of the message to delete
|
|
||||||
MessageID int `json:"message_id"`
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewLiveLocation creates EditMessageLiveLocationParameters only with required
|
||||||
|
// parameters.
|
||||||
|
func NewLiveLocation(latitude, longitude float32) *EditMessageLiveLocationParameters {
|
||||||
|
return &EditMessageLiveLocationParameters{
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewMessageText creates EditMessageTextParameters only with required parameters.
|
// NewMessageText creates EditMessageTextParameters only with required parameters.
|
||||||
func NewMessageText(text string) *EditMessageTextParameters {
|
func NewMessageText(text string) *EditMessageTextParameters {
|
||||||
return &EditMessageTextParameters{
|
return &EditMessageTextParameters{
|
||||||
|
@ -112,42 +136,63 @@ func NewMessageText(text string) *EditMessageTextParameters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EditMessageLiveLocation edit live location messages sent by the bot or via the
|
||||||
|
// bot (for inline bots). A location can be edited until its live_period expires
|
||||||
|
// or editing is explicitly disabled by a call to stopMessageLiveLocation. On
|
||||||
|
// success, if the edited message was sent by the bot, the edited Message is
|
||||||
|
// returned, otherwise True is returned.
|
||||||
|
func (bot *Bot) EditMessageLiveLocation(params *EditMessageLiveLocationParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodEditMessageLiveLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
// EditMessageText edit text and game messages sent by the bot or via the bot
|
// EditMessageText edit text and game messages sent by the bot or via the bot
|
||||||
// (for inline bots). On success, if edited message is sent by the bot, the
|
// (for inline bots). On success, if edited message is sent by the bot, the
|
||||||
// edited Message is returned, otherwise True is returned.
|
// edited Message is returned, otherwise True is returned.
|
||||||
func (bot *Bot) EditMessageText(params *EditMessageTextParameters) (msg *Message, err error) {
|
func (bot *Bot) EditMessageText(params *EditMessageTextParameters) (*Message, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodEditMessageText)
|
resp, err := bot.request(dst, MethodEditMessageText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(Message)
|
var msg Message
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
return
|
return &msg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditMessageCaption edit captions of messages sent by the bot or via the bot
|
// EditMessageCaption edit captions of messages sent by the bot or via the bot
|
||||||
// (for inline bots). On success, if edited message is sent by the bot, the
|
// (for inline bots). On success, if edited message is sent by the bot, the
|
||||||
// edited Message is returned, otherwise True is returned.
|
// edited Message is returned, otherwise True is returned.
|
||||||
func (bot *Bot) EditMessageCaption(params *EditMessageCaptionParameters) (msg *Message, err error) {
|
func (bot *Bot) EditMessageCaption(params *EditMessageCaptionParameters) (*Message, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodEditMessageCaption)
|
resp, err := bot.request(dst, MethodEditMessageCaption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(Message)
|
var msg Message
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
return
|
return &msg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditMessageMedia edit audio, document, photo, or video messages. If a message
|
// EditMessageMedia edit audio, document, photo, or video messages. If a message
|
||||||
|
@ -156,63 +201,37 @@ func (bot *Bot) EditMessageCaption(params *EditMessageCaptionParameters) (msg *M
|
||||||
// edited, new file can't be uploaded. Use previously uploaded file via its
|
// edited, new file can't be uploaded. Use previously uploaded file via its
|
||||||
// file_id or specify a URL. On success, if the edited message was sent by the
|
// file_id or specify a URL. On success, if the edited message was sent by the
|
||||||
// bot, the edited Message is returned, otherwise True is returned.
|
// bot, the edited Message is returned, otherwise True is returned.
|
||||||
func (b *Bot) EditMessageMedia(emmp *EditMessageMediaParameters) (msg *Message, err error) {
|
func (b *Bot) EditMessageMedia(emmp *EditMessageMediaParameters) (*Message, error) {
|
||||||
var src []byte
|
src, err := parser.Marshal(emmp)
|
||||||
src, err = json.Marshal(emmp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := b.request(src, MethodEditMessageMedia)
|
resp, err := b.request(src, MethodEditMessageMedia)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(Message)
|
var msg Message
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
return
|
return &msg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditMessageReplyMarkup edit only the reply markup of messages sent by the bot
|
// EditMessageReplyMarkup edit only the reply markup of messages sent by the bot
|
||||||
// or via the bot (for inline bots). On success, if edited message is sent by the
|
// or via the bot (for inline bots). On success, if edited message is sent by the
|
||||||
// bot, the edited Message is returned, otherwise True is returned.
|
// bot, the edited Message is returned, otherwise True is returned.
|
||||||
func (bot *Bot) EditMessageReplyMarkup(params *EditMessageReplyMarkupParameters) (msg *Message, err error) {
|
func (bot *Bot) EditMessageReplyMarkup(params *EditMessageReplyMarkupParameters) (*Message, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodEditMessageReplyMarkup)
|
resp, err := bot.request(dst, MethodEditMessageReplyMarkup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(Message)
|
var msg Message
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
return
|
return &msg, err
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMessage delete a message, including service messages, with the following
|
|
||||||
// limitations: A message can only be deleted if it was sent less than 48 hours
|
|
||||||
// ago; Bots can delete outgoing messages in groups and supergroups; Bots granted
|
|
||||||
// can_post_messages permissions can delete outgoing messages in channels; If the
|
|
||||||
// bot is an administrator of a group, it can delete any message there; If the
|
|
||||||
// bot has can_delete_messages permission in a supergroup or a channel, it can
|
|
||||||
// delete any message there. Returns True on success.
|
|
||||||
func (bot *Bot) DeleteMessage(chatID int64, messageID int) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&DeleteMessageParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
MessageID: messageID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodDeleteMessage)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
}
|
|
@ -1,59 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// EditMessageLiveLocationParameters represents data for EditMessageLiveLocation
|
|
||||||
// method.
|
|
||||||
type EditMessageLiveLocationParameters struct {
|
|
||||||
// Required if inline_message_id is not specified. Unique identifier for the
|
|
||||||
// target chat or username of the target channel (in the format
|
|
||||||
// @channelusername)
|
|
||||||
ChatID int64 `json:"chat_id,omitempty"`
|
|
||||||
|
|
||||||
// Required if inline_message_id is not specified. Identifier of the sent
|
|
||||||
// message
|
|
||||||
MessageID int `json:"message_id,omitempty"`
|
|
||||||
|
|
||||||
// Required if chat_id and message_id are not specified. Identifier of the
|
|
||||||
// inline message
|
|
||||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Latitude of new location
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of new location
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for a new inline keyboard.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLiveLocation creates EditMessageLiveLocationParameters only with required
|
|
||||||
// parameters.
|
|
||||||
func NewLiveLocation(latitude, longitude float32) *EditMessageLiveLocationParameters {
|
|
||||||
return &EditMessageLiveLocationParameters{
|
|
||||||
Latitude: latitude,
|
|
||||||
Longitude: longitude,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditMessageLiveLocation edit live location messages sent by the bot or via the
|
|
||||||
// bot (for inline bots). A location can be edited until its live_period expires
|
|
||||||
// or editing is explicitly disabled by a call to stopMessageLiveLocation. On
|
|
||||||
// success, if the edited message was sent by the bot, the edited Message is
|
|
||||||
// returned, otherwise True is returned.
|
|
||||||
func (bot *Bot) EditMessageLiveLocation(params *EditMessageLiveLocationParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodEditMessageLiveLocation)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// ExportChatInviteLinkParameters represents data for ExportChatInviteLink method.
|
// ExportChatInviteLinkParameters represents data for ExportChatInviteLink method.
|
||||||
type ExportChatInviteLinkParameters struct {
|
type ExportChatInviteLinkParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -11,17 +9,18 @@ type ExportChatInviteLinkParameters struct {
|
||||||
// ExportChatInviteLink export an invite link to a supergroup or a channel. The
|
// ExportChatInviteLink export an invite link to a supergroup or a channel. The
|
||||||
// bot must be an administrator in the chat for this to work and must have the
|
// bot must be an administrator in the chat for this to work and must have the
|
||||||
// appropriate admin rights. Returns exported invite link as String on success.
|
// appropriate admin rights. Returns exported invite link as String on success.
|
||||||
func (bot *Bot) ExportChatInviteLink(chatID int64) (inviteLink string, err error) {
|
func (bot *Bot) ExportChatInviteLink(chatID int64) (string, error) {
|
||||||
dst, err := json.Marshal(&ExportChatInviteLinkParameters{ChatID: chatID})
|
dst, err := parser.Marshal(&ExportChatInviteLinkParameters{ChatID: chatID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodExportChatInviteLink)
|
resp, err := bot.request(dst, MethodExportChatInviteLink)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &inviteLink)
|
var inviteLink string
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &inviteLink)
|
||||||
|
return inviteLink, err
|
||||||
}
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// ForwardMessageParameters represents data for ForwardMessage method.
|
// ForwardMessageParameters represents data for ForwardMessage method.
|
||||||
type ForwardMessageParameters struct {
|
type ForwardMessageParameters struct {
|
||||||
// Unique identifier for the target chat or username of the target
|
// Unique identifier for the target chat or username of the target
|
||||||
|
@ -30,18 +28,18 @@ func NewForwardMessage(from, to int64, messageID int) *ForwardMessageParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForwardMessage forward messages of any kind. On success, the sent Message is returned.
|
// ForwardMessage forward messages of any kind. On success, the sent Message is returned.
|
||||||
func (bot *Bot) ForwardMessage(params *ForwardMessageParameters) (msg *Message, err error) {
|
func (bot *Bot) ForwardMessage(params *ForwardMessageParameters) (*Message, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodForwardMessage)
|
resp, err := bot.request(dst, MethodForwardMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = new(Message)
|
var msg Message
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
return
|
return &msg, err
|
||||||
}
|
}
|
|
@ -0,0 +1,314 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
type (
|
||||||
|
// GetChatParameters represents data for GetChat method.
|
||||||
|
GetChatParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatAdministratorsParameters represents data for GetChatAdministrators
|
||||||
|
// method.
|
||||||
|
GetChatAdministratorsParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMemberParameters represents data for GetChatMember method.
|
||||||
|
GetChatMemberParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Unique identifier of the target user
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMembersCountParameters represents data for GetChatMembersCount method.
|
||||||
|
GetChatMembersCountParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileParameters represents data for GetFile method.
|
||||||
|
GetFileParameters struct {
|
||||||
|
// File identifier to get info about
|
||||||
|
FileID string `json:"file_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpdatesParameters represents data for GetUpdates method.
|
||||||
|
GetUpdatesParameters struct {
|
||||||
|
// Identifier of the first update to be returned. Must be greater by one than the highest among the
|
||||||
|
// identifiers of previously received updates. By default, updates starting with the earliest unconfirmed
|
||||||
|
// update are returned. An update is considered confirmed as soon as getUpdates is called with an offset
|
||||||
|
// higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset
|
||||||
|
// update from the end of the updates queue. All previous updates will forgotten.
|
||||||
|
Offset int `json:"offset,omitempty"`
|
||||||
|
|
||||||
|
// Limits the number of updates to be retrieved. Values between 1—100 are accepted. Defaults to 100.
|
||||||
|
Limit int `json:"limit,omitempty"`
|
||||||
|
|
||||||
|
// Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short
|
||||||
|
// polling should be used for testing purposes only.
|
||||||
|
Timeout int `json:"timeout,omitempty"`
|
||||||
|
|
||||||
|
// List the types of updates you want your bot to receive. For example, specify ["message",
|
||||||
|
// "edited_channel_post", "callback_query"] to only receive updates of these types. See Update for a complete
|
||||||
|
// list of available update types. Specify an empty list to receive all updates regardless of type (default).
|
||||||
|
// If not specified, the previous setting will be used.
|
||||||
|
//
|
||||||
|
// Please note that this parameter doesn't affect updates created before the call to the getUpdates, so
|
||||||
|
// unwanted updates may be received for a short period of time.
|
||||||
|
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserProfilePhotosParameters represents data for GetUserProfilePhotos method.
|
||||||
|
GetUserProfilePhotosParameters struct {
|
||||||
|
// Unique identifier of the target user
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// Sequential number of the first photo to be returned. By default, all
|
||||||
|
// photos are returned.
|
||||||
|
Offset int `json:"offset,omitempty"`
|
||||||
|
|
||||||
|
// Limits the number of photos to be retrieved. Values between 1—100 are
|
||||||
|
// accepted. Defaults to 100.
|
||||||
|
Limit int `json:"limit,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGameHighScoresParameters represents data for GetGameHighScores method.
|
||||||
|
GetGameHighScoresParameters struct {
|
||||||
|
// Target user id
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// Required if inline_message_id is not specified. Identifier of the sent
|
||||||
|
// message
|
||||||
|
MessageID int `json:"message_id,omitempty"`
|
||||||
|
|
||||||
|
// Required if inline_message_id is not specified. Unique identifier for the
|
||||||
|
// target chat
|
||||||
|
ChatID int64 `json:"chat_id,omitempty"`
|
||||||
|
|
||||||
|
// Required if chat_id and message_id are not specified. Identifier of the
|
||||||
|
// inline message
|
||||||
|
InlineMessageID string `json:"inline_message_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStickerSetParameters represents data for GetStickerSet method.
|
||||||
|
GetStickerSetParameters struct {
|
||||||
|
// Name of the sticker set
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGameHighScores creates GetGameHighScoresParameters only with required parameters.
|
||||||
|
func NewGameHighScores(userID int) *GetGameHighScoresParameters {
|
||||||
|
return &GetGameHighScoresParameters{
|
||||||
|
UserID: userID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChat get up to date information about the chat (current name of the user
|
||||||
|
// for one-on-one conversations, current username of a user, group or channel,
|
||||||
|
// etc.). Returns a Chat object on success.
|
||||||
|
func (bot *Bot) GetChat(chatID int64) (*Chat, error) {
|
||||||
|
dst, err := parser.Marshal(&GetChatParameters{ChatID: chatID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetChat)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var chat Chat
|
||||||
|
err = parser.Unmarshal(resp.Result, &chat)
|
||||||
|
return &chat, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatAdministrators get a list of administrators in a chat. On success,
|
||||||
|
// returns an Array of ChatMember objects that contains information about all
|
||||||
|
// chat administrators except other bots. If the chat is a group or a supergroup
|
||||||
|
// and no administrators were appointed, only the creator will be returned.
|
||||||
|
func (bot *Bot) GetChatAdministrators(chatID int64) ([]ChatMember, error) {
|
||||||
|
dst, err := parser.Marshal(&GetChatAdministratorsParameters{ChatID: chatID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetChatAdministrators)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var chatMembers []ChatMember
|
||||||
|
err = parser.Unmarshal(resp.Result, &chatMembers)
|
||||||
|
return chatMembers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMember get information about a member of a chat. Returns a ChatMember
|
||||||
|
// object on success.
|
||||||
|
func (bot *Bot) GetChatMember(chatID int64, userID int) (*ChatMember, error) {
|
||||||
|
dst, err := parser.Marshal(&GetChatMemberParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
UserID: userID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetChatMember)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var chatMember ChatMember
|
||||||
|
err = parser.Unmarshal(resp.Result, &chatMember)
|
||||||
|
return &chatMember, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChatMembersCount get the number of members in a chat. Returns Int on
|
||||||
|
// success.
|
||||||
|
func (bot *Bot) GetChatMembersCount(chatID int64) (int, error) {
|
||||||
|
dst, err := parser.Marshal(&GetChatMembersCountParameters{ChatID: chatID})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetChatMembersCount)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int
|
||||||
|
err = parser.Unmarshal(resp.Result, &count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFile get basic info about a file and prepare it for downloading. For the
|
||||||
|
// moment, bots can download files of up to 20MB in size. On success, a File
|
||||||
|
// object is returned. The file can then be downloaded via the link
|
||||||
|
// https://api.telegram.org/file/bot<token>/<file_path>, where <file_path> is
|
||||||
|
// taken from the response. It is guaranteed that the link will be valid for at
|
||||||
|
// least 1 hour. When the link expires, a new one can be requested by calling
|
||||||
|
// getFile again.
|
||||||
|
//
|
||||||
|
// Note: This function may not preserve the original file name and MIME type. You
|
||||||
|
// should save the file's MIME type and name (if available) when the File object
|
||||||
|
// is received.
|
||||||
|
func (bot *Bot) GetFile(fileID string) (*File, error) {
|
||||||
|
dst, err := parser.Marshal(&GetFileParameters{FileID: fileID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var file File
|
||||||
|
err = parser.Unmarshal(resp.Result, &file)
|
||||||
|
return &file, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMe testing your bot's auth token. Requires no parameters. Returns basic
|
||||||
|
// information about the bot in form of a User object.
|
||||||
|
func (bot *Bot) GetMe() (*User, error) {
|
||||||
|
resp, err := bot.request(nil, MethodGetMe)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var me User
|
||||||
|
err = parser.Unmarshal(resp.Result, &me)
|
||||||
|
return &me, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUpdates receive incoming updates using long polling. An Array of Update objects is returned.
|
||||||
|
func (bot *Bot) GetUpdates(params *GetUpdatesParameters) ([]Update, error) {
|
||||||
|
if params == nil {
|
||||||
|
params = &GetUpdatesParameters{Limit: 100}
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(src, MethodGetUpdates)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := make([]Update, params.Limit)
|
||||||
|
err = parser.Unmarshal(resp.Result, &updates)
|
||||||
|
return updates, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserProfilePhotos get a list of profile pictures for a user. Returns a UserProfilePhotos object.
|
||||||
|
func (bot *Bot) GetUserProfilePhotos(params *GetUserProfilePhotosParameters) (*UserProfilePhotos, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetUserProfilePhotos)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var photos UserProfilePhotos
|
||||||
|
err = parser.Unmarshal(resp.Result, &photos)
|
||||||
|
return &photos, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWebhookInfo get current webhook status. Requires no parameters. On success,
|
||||||
|
// returns a WebhookInfo object. If the bot is using getUpdates, will return an
|
||||||
|
// object with the url field empty.
|
||||||
|
func (bot *Bot) GetWebhookInfo() (*WebhookInfo, error) {
|
||||||
|
resp, err := bot.request(nil, MethodGetWebhookInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var info WebhookInfo
|
||||||
|
err = parser.Unmarshal(resp.Result, &info)
|
||||||
|
return &info, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGameHighScores get data for high score tables. Will return the score of the
|
||||||
|
// specified user and several of his neighbors in a game. On success, returns an
|
||||||
|
// Array of GameHighScore objects.
|
||||||
|
func (bot *Bot) GetGameHighScores(params *GetGameHighScoresParameters) ([]GameHighScore, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetGameHighScores)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var scores []GameHighScore
|
||||||
|
err = parser.Unmarshal(resp.Result, &scores)
|
||||||
|
return scores, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStickerSet get a sticker set. On success, a StickerSet object is returned.
|
||||||
|
func (bot *Bot) GetStickerSet(name string) (*StickerSet, error) {
|
||||||
|
dst, err := parser.Marshal(&GetStickerSetParameters{Name: name})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodGetStickerSet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var set StickerSet
|
||||||
|
err = parser.Unmarshal(resp.Result, &set)
|
||||||
|
return &set, err
|
||||||
|
}
|
28
get_chat.go
28
get_chat.go
|
@ -1,28 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetChatParameters represents data for GetChat method.
|
|
||||||
type GetChatParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChat get up to date information about the chat (current name of the user
|
|
||||||
// for one-on-one conversations, current username of a user, group or channel,
|
|
||||||
// etc.). Returns a Chat object on success.
|
|
||||||
func (bot *Bot) GetChat(chatID int64) (chat *Chat, err error) {
|
|
||||||
dst, err := json.Marshal(&GetChatParameters{ChatID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetChat)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
chat = new(Chat)
|
|
||||||
err = json.Unmarshal(*resp.Result, chat)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetChatAdministratorsParameters represents data for GetChatAdministrators
|
|
||||||
// method.
|
|
||||||
type GetChatAdministratorsParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChatAdministrators get a list of administrators in a chat. On success,
|
|
||||||
// returns an Array of ChatMember objects that contains information about all
|
|
||||||
// chat administrators except other bots. If the chat is a group or a supergroup
|
|
||||||
// and no administrators were appointed, only the creator will be returned.
|
|
||||||
func (bot *Bot) GetChatAdministrators(chatID int64) (members []ChatMember, err error) {
|
|
||||||
dst, err := json.Marshal(&GetChatAdministratorsParameters{ChatID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetChatAdministrators)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &members)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetChatMemberParameters represents data for GetChatMember method.
|
|
||||||
type GetChatMemberParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Unique identifier of the target user
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChatMember get information about a member of a chat. Returns a ChatMember
|
|
||||||
// object on success.
|
|
||||||
func (bot *Bot) GetChatMember(chatID int64, userID int) (member *ChatMember, err error) {
|
|
||||||
dst, err := json.Marshal(&GetChatMemberParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
UserID: userID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetChatMember)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
member = new(ChatMember)
|
|
||||||
err = json.Unmarshal(*resp.Result, member)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetChatMembersCountParameters represents data for GetChatMembersCount method.
|
|
||||||
type GetChatMembersCountParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChatMembersCount get the number of members in a chat. Returns Int on
|
|
||||||
// success.
|
|
||||||
func (bot *Bot) GetChatMembersCount(chatID int64) (count int, err error) {
|
|
||||||
dst, err := json.Marshal(&GetChatMembersCountParameters{ChatID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetChatMembersCount)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &count)
|
|
||||||
return
|
|
||||||
}
|
|
36
get_file.go
36
get_file.go
|
@ -1,36 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetFileParameters represents data for GetFile method.
|
|
||||||
type GetFileParameters struct {
|
|
||||||
// File identifier to get info about
|
|
||||||
FileID string `json:"file_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFile get basic info about a file and prepare it for downloading. For the
|
|
||||||
// moment, bots can download files of up to 20MB in size. On success, a File
|
|
||||||
// object is returned. The file can then be downloaded via the link
|
|
||||||
// https://api.telegram.org/file/bot<token>/<file_path>, where <file_path> is
|
|
||||||
// taken from the response. It is guaranteed that the link will be valid for at
|
|
||||||
// least 1 hour. When the link expires, a new one can be requested by calling
|
|
||||||
// getFile again.
|
|
||||||
//
|
|
||||||
// Note: This function may not preserve the original file name and MIME type. You
|
|
||||||
// should save the file's MIME type and name (if available) when the File object
|
|
||||||
// is received.
|
|
||||||
func (bot *Bot) GetFile(fileID string) (file *File, err error) {
|
|
||||||
dst, err := json.Marshal(&GetFileParameters{FileID: fileID})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetFile)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
file = new(File)
|
|
||||||
err = json.Unmarshal(*resp.Result, file)
|
|
||||||
return
|
|
||||||
}
|
|
16
get_me.go
16
get_me.go
|
@ -1,16 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetMe testing your bot's auth token. Requires no parameters. Returns basic
|
|
||||||
// information about the bot in form of a User object.
|
|
||||||
func (bot *Bot) GetMe() (me *User, err error) {
|
|
||||||
resp, err := bot.request(nil, MethodGetMe)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
me = new(User)
|
|
||||||
err = json.Unmarshal(*resp.Result, me)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetUpdatesParameters represents data for GetUpdates method.
|
|
||||||
type GetUpdatesParameters struct {
|
|
||||||
// Identifier of the first update to be returned. Must be greater by one than
|
|
||||||
// the highest among the identifiers of previously received updates. By
|
|
||||||
// default, updates starting with the earliest unconfirmed update are
|
|
||||||
// returned. An update is considered confirmed as soon as getUpdates is
|
|
||||||
// called with an offset higher than its update_id. The negative offset can
|
|
||||||
// be specified to retrieve updates starting from -offset update from the
|
|
||||||
// end of the updates queue. All previous updates will forgotten.
|
|
||||||
Offset int `json:"offset,omitempty"`
|
|
||||||
|
|
||||||
// Limits the number of updates to be retrieved. Values between 1—100 are
|
|
||||||
// accepted. Defaults to 100.
|
|
||||||
Limit int `json:"limit,omitempty"`
|
|
||||||
|
|
||||||
// Timeout in seconds for long polling. Defaults to 0, i.e. usual short
|
|
||||||
// polling. Should be positive, short polling should be used for testing
|
|
||||||
// purposes only.
|
|
||||||
Timeout int `json:"timeout,omitempty"`
|
|
||||||
|
|
||||||
// List the types of updates you want your bot to receive. For example,
|
|
||||||
// specify [“message”, “edited_channel_post”, “callback_query”] to only
|
|
||||||
// receive updates of these types. See Update for a complete list of
|
|
||||||
// available update types. Specify an empty list to receive all updates
|
|
||||||
// regardless of type (default). If not specified, the previous setting will
|
|
||||||
// be used.
|
|
||||||
//
|
|
||||||
// Please note that this parameter doesn't affect updates created before the
|
|
||||||
// call to the getUpdates, so unwanted updates may be received for a short
|
|
||||||
// period of time.
|
|
||||||
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUpdates receive incoming updates using long polling. An Array of
|
|
||||||
// Update objects is returned.
|
|
||||||
func (bot *Bot) GetUpdates(params *GetUpdatesParameters) (updates []Update, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetUpdates)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if params == nil {
|
|
||||||
params = new(GetUpdatesParameters)
|
|
||||||
params.Limit = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
updates = make([]Update, params.Limit)
|
|
||||||
err = json.Unmarshal(*resp.Result, &updates)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetUserProfilePhotosParameters represents data for GetUserProfilePhotos method.
|
|
||||||
type GetUserProfilePhotosParameters struct {
|
|
||||||
// Unique identifier of the target user
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// Sequential number of the first photo to be returned. By default, all
|
|
||||||
// photos are returned.
|
|
||||||
Offset int `json:"offset,omitempty"`
|
|
||||||
|
|
||||||
// Limits the number of photos to be retrieved. Values between 1—100 are
|
|
||||||
// accepted. Defaults to 100.
|
|
||||||
Limit int `json:"limit,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserProfilePhotos get a list of profile pictures for a user. Returns a UserProfilePhotos object.
|
|
||||||
func (bot *Bot) GetUserProfilePhotos(params *GetUserProfilePhotosParameters) (photos *UserProfilePhotos, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetUserProfilePhotos)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
photos = new(UserProfilePhotos)
|
|
||||||
err = json.Unmarshal(*resp.Result, photos)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// GetWebhookInfo get current webhook status. Requires no parameters. On success,
|
|
||||||
// returns a WebhookInfo object. If the bot is using getUpdates, will return an
|
|
||||||
// object with the url field empty.
|
|
||||||
func (bot *Bot) GetWebhookInfo() (info *WebhookInfo, err error) {
|
|
||||||
resp, err := bot.request(nil, MethodGetWebhookInfo)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
info = new(WebhookInfo)
|
|
||||||
err = json.Unmarshal(*resp.Result, info)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
module gitlab.com/toby3d/telegram
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/buaazp/fasthttprouter v0.1.1
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.6
|
||||||
|
github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9
|
||||||
|
github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc // indirect
|
||||||
|
github.com/klauspost/compress v1.7.4 // indirect
|
||||||
|
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
github.com/valyala/fasthttp v1.4.0
|
||||||
|
golang.org/x/text v0.3.2
|
||||||
|
)
|
|
@ -0,0 +1,38 @@
|
||||||
|
github.com/buaazp/fasthttprouter v0.1.1 h1:4oAnN0C3xZjylvZJdP35cxfclyn4TYkW6Y+DSvS+h8Q=
|
||||||
|
github.com/buaazp/fasthttprouter v0.1.1/go.mod h1:h/Ap5oRVLeItGKTVBb+heQPks+HdIUtGmI4H5WCYijM=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
|
github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9 h1:mA7k8E2Vrmyj5CW/D1XZBFmohVNi7jf757vibGwzRbo=
|
||||||
|
github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9/go.mod h1:l8CN7iyX1k2xlsTYVTpCtwBPcxThf/jLWDGVcF6T/bM=
|
||||||
|
github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc h1:OkOhOn3WBUmfATC1NsA3rBlgHGkjk0KGnR5akl/8uXc=
|
||||||
|
github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc/go.mod h1:Bt95qRxLvpdmASW9s2tTxGdQ5ma4o4n8QFhCvzCew/M=
|
||||||
|
github.com/klauspost/compress v1.4.0 h1:8nsMz3tWa9SWWPL60G1V6CUsf4lLjWLTNEtibhe8gh8=
|
||||||
|
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/compress v1.7.4 h1:4UqAIzZ1Ns2epCTyJ1d2xMWvxtX+FNSCYWeOFogK9nc=
|
||||||
|
github.com/klauspost/compress v1.7.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e h1:+lIPJOWl+jSiJOc70QXJ07+2eg2Jy2EC7Mi11BWujeM=
|
||||||
|
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasthttp v1.4.0 h1:PuaTGZIw3mjYhhhbVbCQp8aciRZN9YdoB7MGX9Ko76A=
|
||||||
|
github.com/valyala/fasthttp v1.4.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
||||||
|
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||||
|
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// KickChatMemberParameters represents data for KickChatMember method.
|
// KickChatMemberParameters represents data for KickChatMember method.
|
||||||
type KickChatMemberParameters struct {
|
type KickChatMemberParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -24,17 +22,18 @@ type KickChatMemberParameters struct {
|
||||||
// Note: In regular groups (non-supergroups), this method will only work if the 'All Members Are
|
// Note: In regular groups (non-supergroups), this method will only work if the 'All Members Are
|
||||||
// Admins' setting is off in the target group. Otherwise members may only be removed by the group's
|
// Admins' setting is off in the target group. Otherwise members may only be removed by the group's
|
||||||
// creator or by the member that added them.
|
// creator or by the member that added them.
|
||||||
func (bot *Bot) KickChatMember(params *KickChatMemberParameters) (ok bool, err error) {
|
func (bot *Bot) KickChatMember(params *KickChatMemberParameters) (bool, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodKickChatMember)
|
resp, err := bot.request(dst, MethodKickChatMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
var ok bool
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
}
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// LeaveChatParameters represents data for LeaveChat method.
|
// LeaveChatParameters represents data for LeaveChat method.
|
||||||
type LeaveChatParameters struct {
|
type LeaveChatParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -9,17 +7,18 @@ type LeaveChatParameters struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LeaveChat leave a group, supergroup or channel. Returns True on success.
|
// LeaveChat leave a group, supergroup or channel. Returns True on success.
|
||||||
func (bot *Bot) LeaveChat(chatID int64) (ok bool, err error) {
|
func (bot *Bot) LeaveChat(chatID int64) (bool, error) {
|
||||||
dst, err := json.Marshal(&LeaveChatParameters{ChatID: chatID})
|
dst, err := parser.Marshal(&LeaveChatParameters{ChatID: chatID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodLeaveChat)
|
resp, err := bot.request(dst, MethodLeaveChat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
var ok bool
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
}
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
package login
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CheckAuthorization verify the authentication and the integrity of the data
|
|
||||||
// received by comparing the received hash parameter with the hexadecimal
|
|
||||||
// representation of the HMAC-SHA-256 signature of the data-check-string with the
|
|
||||||
// SHA256 hash of the bot's token used as a secret key.
|
|
||||||
func CheckAuthorization(data interface{}, secretKey string) (bool, error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
|
|
||||||
switch d := data.(type) {
|
|
||||||
case *User:
|
|
||||||
return d.CheckAuthorization(secretKey)
|
|
||||||
case *http.Args:
|
|
||||||
d.CopyTo(args)
|
|
||||||
http.ReleaseArgs(d)
|
|
||||||
case []byte:
|
|
||||||
args.ParseBytes(d)
|
|
||||||
case string:
|
|
||||||
args.Parse(d)
|
|
||||||
default:
|
|
||||||
return false, ErrUnsupportedType
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := args.Peek(KeyHash)
|
|
||||||
args.Del(KeyHash)
|
|
||||||
|
|
||||||
return check(args.QueryString(), []byte(secretKey), hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckAuthorization verify the authentication and the integrity of the data
|
|
||||||
// received by comparing the received hash parameter with the hexadecimal
|
|
||||||
// representation of the HMAC-SHA-256 signature of the data-check-string with the
|
|
||||||
// SHA256 hash of the bot's token used as a secret key.
|
|
||||||
func (u *User) CheckAuthorization(secretKey string) (ok bool, err error) {
|
|
||||||
args := u.toArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
hash := args.Peek(KeyHash)
|
|
||||||
args.Del(KeyHash)
|
|
||||||
|
|
||||||
return check(args.QueryString(), []byte(secretKey), hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(data, secretKey, hash []byte) (bool, error) {
|
|
||||||
sk := sha256.Sum256(secretKey)
|
|
||||||
h := hmac.New(sha256.New, sk[0:])
|
|
||||||
if _, err := h.Write(data); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return hex.EncodeToString(h.Sum(nil)) == string(hash), nil
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
package login_test
|
package login_test
|
||||||
|
|
||||||
|
/*
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -40,3 +41,4 @@ func Example_fastStart() {
|
||||||
log.Fatalln(err.Error())
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Widget struct {
|
||||||
|
accessToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
// User contains data about authenticated user.
|
||||||
|
User struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
AuthDate int64 `json:"auth_date"`
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
LastName string `json:"last_name,omitempty"`
|
||||||
|
PhotoURL string `json:"photo_url,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Key represents available and supported query arguments keys.
|
||||||
|
const (
|
||||||
|
KeyAuthDate = "auth_date"
|
||||||
|
KeyFirstName = "first_name"
|
||||||
|
KeyHash = "hash"
|
||||||
|
KeyID = "id"
|
||||||
|
KeyLastName = "last_name"
|
||||||
|
KeyPhotoURL = "photo_url"
|
||||||
|
KeyUsername = "username"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewWidget(accessToken string) *Widget {
|
||||||
|
return &Widget{accessToken: accessToken}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckAuthorization verify the authentication and the integrity of the data
|
||||||
|
// received by comparing the received hash parameter with the hexadecimal
|
||||||
|
// representation of the HMAC-SHA-256 signature of the data-check-string with the
|
||||||
|
// SHA256 hash of the bot's token used as a secret key.
|
||||||
|
func (w *Widget) CheckAuthorization(u User) (bool, error) {
|
||||||
|
hash, err := w.GenerateHash(u)
|
||||||
|
return hash == u.Hash, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Widget) GenerateHash(u User) (string, error) {
|
||||||
|
a := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(a)
|
||||||
|
|
||||||
|
// WARN: do not change order of this args, it must be alphabetical
|
||||||
|
a.SetUint(KeyAuthDate, int(u.AuthDate))
|
||||||
|
a.Set(KeyFirstName, u.FirstName)
|
||||||
|
a.SetUint(KeyID, u.ID)
|
||||||
|
if u.LastName != "" {
|
||||||
|
a.Set(KeyLastName, u.LastName)
|
||||||
|
}
|
||||||
|
if u.PhotoURL != "" {
|
||||||
|
a.Set(KeyPhotoURL, u.PhotoURL)
|
||||||
|
}
|
||||||
|
if u.Username != "" {
|
||||||
|
a.Set(KeyUsername, u.Username)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretKey := sha256.Sum256([]byte(w.accessToken))
|
||||||
|
h := hmac.New(sha256.New, secretKey[0:])
|
||||||
|
_, err := h.Write(a.QueryString())
|
||||||
|
return hex.EncodeToString(h.Sum(nil)), err
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNew(t *testing.T) {
|
||||||
|
assert.NotNil(t, NewWidget("hackme"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateHash(t *testing.T) {
|
||||||
|
w := NewWidget("hackme")
|
||||||
|
hash, err := w.GenerateHash(User{
|
||||||
|
ID: 123,
|
||||||
|
Username: "toby3d",
|
||||||
|
FirstName: "Maxim",
|
||||||
|
LastName: "Lebedev",
|
||||||
|
AuthDate: time.Now().UTC().Unix(),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckAuthorization(t *testing.T) {
|
||||||
|
w := NewWidget("hackme")
|
||||||
|
u := User{
|
||||||
|
ID: 123,
|
||||||
|
Username: "toby3d",
|
||||||
|
FirstName: "Maxim",
|
||||||
|
LastName: "Lebedev",
|
||||||
|
PhotoURL: "https://toby3d.me/avatar.jpg",
|
||||||
|
AuthDate: time.Now().UTC().Unix(),
|
||||||
|
}
|
||||||
|
t.Run("invalid", func(t *testing.T) {
|
||||||
|
u.Hash = "wtf"
|
||||||
|
ok, err := w.CheckAuthorization(u)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, ok)
|
||||||
|
})
|
||||||
|
t.Run("valid", func(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
u.Hash, err = w.GenerateHash(u)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, u.Hash)
|
||||||
|
|
||||||
|
ok, err := w.CheckAuthorization(u)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, ok)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,31 +0,0 @@
|
||||||
package login
|
|
||||||
|
|
||||||
import http "github.com/valyala/fasthttp"
|
|
||||||
|
|
||||||
// ParseUser create User structure from input url.Values.
|
|
||||||
func ParseUser(data interface{}) (*User, error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
|
|
||||||
switch d := data.(type) {
|
|
||||||
case *http.Args:
|
|
||||||
d.CopyTo(args)
|
|
||||||
http.ReleaseArgs(d)
|
|
||||||
case []byte:
|
|
||||||
args.ParseBytes(d)
|
|
||||||
case string:
|
|
||||||
args.Parse(d)
|
|
||||||
default:
|
|
||||||
return nil, ErrUnsupportedType
|
|
||||||
}
|
|
||||||
|
|
||||||
return &User{
|
|
||||||
ID: args.GetUintOrZero(KeyID),
|
|
||||||
AuthDate: int64(args.GetUintOrZero(KeyAuthDate)),
|
|
||||||
FirstName: string(args.Peek(KeyFirstName)),
|
|
||||||
Hash: string(args.Peek(KeyHash)),
|
|
||||||
LastName: string(args.Peek(KeyLastName)),
|
|
||||||
PhotoURL: string(args.Peek(KeyPhotoURL)),
|
|
||||||
Username: string(args.Peek(KeyUsername)),
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package login
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// User contains data about authenticated user.
|
|
||||||
type User struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
AuthDate int64 `json:"auth_date"`
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
Hash string `json:"hash"`
|
|
||||||
LastName string `json:"last_name,omitempty"`
|
|
||||||
PhotoURL string `json:"photo_url,omitempty"`
|
|
||||||
Username string `json:"username,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key represents available and supported query arguments keys.
|
|
||||||
const (
|
|
||||||
KeyAuthDate = "auth_date"
|
|
||||||
KeyFirstName = "first_name"
|
|
||||||
KeyHash = "hash"
|
|
||||||
KeyID = "id"
|
|
||||||
KeyLastName = "last_name"
|
|
||||||
KeyPhotoURL = "photo_url"
|
|
||||||
KeyUsername = "username"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrUserNotDefined describes error of an unassigned structure of user.
|
|
||||||
ErrUserNotDefined = errors.New("user is not defined")
|
|
||||||
|
|
||||||
// ErrEmptyToken describes error of an empty access token of the bot.
|
|
||||||
ErrEmptyToken = errors.New("empty bot access token")
|
|
||||||
|
|
||||||
// ErrUnsupportedType describes error of unsupported input data type for
|
|
||||||
// CheckAuthorization method.
|
|
||||||
ErrUnsupportedType = errors.New("unsupported data type")
|
|
||||||
)
|
|
|
@ -1,62 +0,0 @@
|
||||||
package login
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FullName return user first name only or full name if last name is present.
|
|
||||||
func (user *User) FullName() string {
|
|
||||||
if user == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.HasLastName() {
|
|
||||||
return user.FirstName + " " + user.LastName
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.FirstName
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthTime convert AuthDate field into time.Time.
|
|
||||||
func (user *User) AuthTime() *time.Time {
|
|
||||||
if user == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t := time.Unix(user.AuthDate, 0)
|
|
||||||
return &t
|
|
||||||
}
|
|
||||||
|
|
||||||
// HaveLastName checks what the current user has a LastName.
|
|
||||||
func (u *User) HasLastName() bool {
|
|
||||||
return u != nil && u.LastName != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// HaveUsername checks what the current user has a username.
|
|
||||||
func (u *User) HasUsername() bool {
|
|
||||||
return u != nil && u.Username != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) toArgs() *http.Args {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.SetUint(KeyAuthDate, int(u.AuthDate))
|
|
||||||
args.Set(KeyFirstName, u.FirstName)
|
|
||||||
args.SetUint(KeyID, u.ID)
|
|
||||||
args.Set(KeyHash, u.Hash)
|
|
||||||
|
|
||||||
// Add optional values if exist
|
|
||||||
if u.LastName != "" {
|
|
||||||
args.Set(KeyLastName, u.LastName)
|
|
||||||
}
|
|
||||||
if u.PhotoURL != "" {
|
|
||||||
args.Set(KeyPhotoURL, u.PhotoURL)
|
|
||||||
}
|
|
||||||
if u.Username != "" {
|
|
||||||
args.Set(KeyUsername, u.Username)
|
|
||||||
}
|
|
||||||
|
|
||||||
return args
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FullName return user first name only or full name if last name is present.
|
||||||
|
func (u *User) FullName() string {
|
||||||
|
name := u.FirstName
|
||||||
|
if u.HasLastName() {
|
||||||
|
name += " " + u.LastName
|
||||||
|
}
|
||||||
|
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthTime convert AuthDate field into time.Time.
|
||||||
|
func (u *User) AuthTime() *time.Time {
|
||||||
|
if u == nil || u.AuthDate == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
t := time.Unix(u.AuthDate, 0)
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasLastName checks what the current user has a LastName.
|
||||||
|
func (u *User) HasLastName() bool {
|
||||||
|
return u != nil && u.LastName != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasUsername checks what the current user has a username.
|
||||||
|
func (u *User) HasUsername() bool {
|
||||||
|
return u != nil && u.Username != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPhoto checks what the current user has a photo.
|
||||||
|
func (u *User) HasPhoto() bool {
|
||||||
|
return u != nil && u.PhotoURL != ""
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUser(t *testing.T) {
|
||||||
|
t.Run("has last name", func(t *testing.T) {
|
||||||
|
t.Run("false", func(t *testing.T) {
|
||||||
|
var u User
|
||||||
|
assert.False(t, u.HasLastName())
|
||||||
|
})
|
||||||
|
t.Run("true", func(t *testing.T) {
|
||||||
|
u := User{LastName: "Lebedev"}
|
||||||
|
assert.True(t, u.HasLastName())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("has username", func(t *testing.T) {
|
||||||
|
t.Run("false", func(t *testing.T) {
|
||||||
|
var u User
|
||||||
|
assert.False(t, u.HasUsername())
|
||||||
|
})
|
||||||
|
t.Run("true", func(t *testing.T) {
|
||||||
|
u := User{Username: "toby3d"}
|
||||||
|
assert.True(t, u.HasUsername())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("auth time", func(t *testing.T) {
|
||||||
|
t.Run("empty", func(t *testing.T) {
|
||||||
|
var u User
|
||||||
|
assert.Nil(t, u.AuthTime())
|
||||||
|
})
|
||||||
|
t.Run("exists", func(t *testing.T) {
|
||||||
|
u := User{AuthDate: time.Now().UTC().Unix()}
|
||||||
|
assert.NotNil(t, u.AuthTime())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("has photo", func(t *testing.T) {
|
||||||
|
t.Run("empty", func(t *testing.T) {
|
||||||
|
var u User
|
||||||
|
assert.False(t, u.HasPhoto())
|
||||||
|
})
|
||||||
|
t.Run("exists", func(t *testing.T) {
|
||||||
|
u := User{PhotoURL: "https://toby3d.me/avatar.jpg"}
|
||||||
|
assert.True(t, u.HasPhoto())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("full name", func(t *testing.T) {
|
||||||
|
t.Run("empty", func(t *testing.T) {
|
||||||
|
var u User
|
||||||
|
assert.Empty(t, u.FullName())
|
||||||
|
})
|
||||||
|
t.Run("first name", func(t *testing.T) {
|
||||||
|
u := User{
|
||||||
|
FirstName: "Maxim",
|
||||||
|
}
|
||||||
|
assert.Equal(t, u.FirstName, u.FullName())
|
||||||
|
})
|
||||||
|
t.Run("first & last name", func(t *testing.T) {
|
||||||
|
u := User{
|
||||||
|
FirstName: "Maxim",
|
||||||
|
LastName: "Lebedev",
|
||||||
|
}
|
||||||
|
assert.Equal(t, u.FirstName+" "+u.LastName, u.FullName())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
152
methods_games.go
152
methods_games.go
|
@ -1,152 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
type (
|
|
||||||
// SendGameParameters represents data for SendGame method.
|
|
||||||
SendGameParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Short name of the game, serves as the unique identifier for the game. Set
|
|
||||||
// up your games via Botfather.
|
|
||||||
GameShortName string `json:"game_short_name"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for an inline keyboard. If empty, one ‘Play
|
|
||||||
// game_title’ button will be shown. If not empty, the first button must
|
|
||||||
// launch the game.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGameScoreParameters represents data for SetGameScore method.
|
|
||||||
SetGameScoreParameters struct {
|
|
||||||
// User identifier
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// New score, must be non-negative
|
|
||||||
Score int `json:"score"`
|
|
||||||
|
|
||||||
// Required if inline_message_id is not specified. Identifier of the sent
|
|
||||||
// message
|
|
||||||
MessageID int `json:"message_id,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if the high score is allowed to decrease. This can be useful
|
|
||||||
// when fixing mistakes or banning cheaters
|
|
||||||
Force bool `json:"force,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if the game message should not be automatically edited to
|
|
||||||
// include the current scoreboard
|
|
||||||
DisableEditMessage bool `json:"disable_edit_message,omitempty"`
|
|
||||||
|
|
||||||
// Required if inline_message_id is not specified. Unique identifier for the
|
|
||||||
// target chat
|
|
||||||
ChatID int64 `json:"chat_id,omitempty"`
|
|
||||||
|
|
||||||
// Required if chat_id and message_id are not specified. Identifier of the
|
|
||||||
// inline message
|
|
||||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGameHighScoresParameters represents data for GetGameHighScores method.
|
|
||||||
GetGameHighScoresParameters struct {
|
|
||||||
// Target user id
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// Required if inline_message_id is not specified. Identifier of the sent
|
|
||||||
// message
|
|
||||||
MessageID int `json:"message_id,omitempty"`
|
|
||||||
|
|
||||||
// Required if inline_message_id is not specified. Unique identifier for the
|
|
||||||
// target chat
|
|
||||||
ChatID int64 `json:"chat_id,omitempty"`
|
|
||||||
|
|
||||||
// Required if chat_id and message_id are not specified. Identifier of the
|
|
||||||
// inline message
|
|
||||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewGame creates SendGameParameters only with required parameters.
|
|
||||||
func NewGame(chatID int64, gameShortName string) *SendGameParameters {
|
|
||||||
return &SendGameParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
GameShortName: gameShortName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendGame send a game. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendGame(params *SendGameParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendGame)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGameScore creates SetGameScoreParameters only with required parameters.
|
|
||||||
func NewGameScore(userID, score int) *SetGameScoreParameters {
|
|
||||||
return &SetGameScoreParameters{
|
|
||||||
UserID: userID,
|
|
||||||
Score: score,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGameScore set the score of the specified user in a game. On success, if the
|
|
||||||
// message was sent by the bot, returns the edited Message, otherwise returns
|
|
||||||
// True. Returns an error, if the new score is not greater than the user's
|
|
||||||
// current score in the chat and force is False.
|
|
||||||
func (bot *Bot) SetGameScore(params *SetGameScoreParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSetGameScore)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGameHighScores creates GetGameHighScoresParameters only with required parameters.
|
|
||||||
func NewGameHighScores(userID int) *GetGameHighScoresParameters {
|
|
||||||
return &GetGameHighScoresParameters{
|
|
||||||
UserID: userID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGameHighScores get data for high score tables. Will return the score of the
|
|
||||||
// specified user and several of his neighbors in a game. On success, returns an
|
|
||||||
// Array of GameHighScore objects.
|
|
||||||
func (bot *Bot) GetGameHighScores(params *GetGameHighScoresParameters) (scores []GameHighScore, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetGameHighScores)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &scores)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// AnswerInlineQueryParameters represents data for AnswerInlineQuery method.
|
|
||||||
type AnswerInlineQueryParameters struct {
|
|
||||||
// Unique identifier for the answered query
|
|
||||||
InlineQueryID string `json:"inline_query_id"`
|
|
||||||
|
|
||||||
// Pass the offset that a client should send in the next query with the same
|
|
||||||
// text to receive more results. Pass an empty string if there are no more
|
|
||||||
// results or if you don‘t support pagination. Offset length can’t exceed 64
|
|
||||||
// bytes.
|
|
||||||
NextOffset string `json:"next_offset,omitempty"`
|
|
||||||
|
|
||||||
// If passed, clients will display a button with specified text that switches
|
|
||||||
// the user to a private chat with the bot and sends the bot a start message
|
|
||||||
// with the parameter switch_pm_parameter
|
|
||||||
SwitchPrivateMessageText string `json:"switch_pm_text,omitempty"`
|
|
||||||
|
|
||||||
// Deep-linking parameter for the /start message sent to the bot when user
|
|
||||||
// presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and -
|
|
||||||
// are allowed.
|
|
||||||
SwitchPrivateMessageParameter string `json:"switch_pm_parameter,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized array of results for the inline query
|
|
||||||
Results []interface{} `json:"results"`
|
|
||||||
|
|
||||||
// The maximum amount of time in seconds that the result of the inline query
|
|
||||||
// may be cached on the server. Defaults to 300.
|
|
||||||
CacheTime int `json:"cache_time,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if results may be cached on the server side only for the user
|
|
||||||
// that sent the query. By default, results may be returned to any user who
|
|
||||||
// sends the same query
|
|
||||||
IsPersonal bool `json:"is_personal,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAnswerInlineQuery creates AnswerInlineQueryParameters only with required
|
|
||||||
// parameters.
|
|
||||||
func NewAnswerInlineQuery(inlineQueryID string, results ...interface{}) *AnswerInlineQueryParameters {
|
|
||||||
return &AnswerInlineQueryParameters{
|
|
||||||
InlineQueryID: inlineQueryID,
|
|
||||||
Results: results,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnswerInlineQuery send answers to an inline query. On success, True is returned.
|
|
||||||
//
|
|
||||||
// No more than 50 results per query are allowed.
|
|
||||||
func (bot *Bot) AnswerInlineQuery(params *AnswerInlineQueryParameters) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodAnswerInlineQuery)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,279 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// SendStickerParameters represents data for SetSticker method.
|
|
||||||
SendStickerParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Sticker to send
|
|
||||||
Sticker interface{} `json:"sticker"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification
|
|
||||||
// with no sound
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an
|
|
||||||
// inline keyboard, custom reply keyboard, instructions to remove
|
|
||||||
// reply keyboard or to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStickerSetParameters represents data for GetStickerSet method.
|
|
||||||
GetStickerSetParameters struct {
|
|
||||||
// Name of the sticker set
|
|
||||||
Name string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadStickerFileParameters struct {
|
|
||||||
// User identifier of sticker file owner
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// Png image with the sticker, must be up to 512 kilobytes in size,
|
|
||||||
// dimensions must not exceed 512px, and either width or height
|
|
||||||
// must be exactly 512px.
|
|
||||||
PNGSticker interface{} `json:"png_sticker"`
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateNewStickerSetParameters struct {
|
|
||||||
// User identifier of created sticker set owner
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// Short name of sticker set, to be used in t.me/addstickers/ URLs
|
|
||||||
// (e.g., animals). Can contain only english letters, digits and
|
|
||||||
// underscores. Must begin with a letter, can't contain consecutive
|
|
||||||
// underscores and must end in “_by_<bot username>”. <bot_username>
|
|
||||||
// is case insensitive. 1-64 characters.
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Sticker set title, 1-64 characters
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Png image with the sticker, must be up to 512 kilobytes in size,
|
|
||||||
// dimensions must not exceed 512px, and either width or height must
|
|
||||||
// be exactly 512px. Pass a file_id as a String to send a file that
|
|
||||||
// already exists on the Telegram servers, pass an HTTP URL as a
|
|
||||||
// String for Telegram to get a file from the Internet, or upload
|
|
||||||
// a new one using multipart/form-data.
|
|
||||||
PNGSticker interface{} `json:"png_sticker"`
|
|
||||||
|
|
||||||
// One or more emoji corresponding to the sticker
|
|
||||||
Emojis string `json:"emojis"`
|
|
||||||
|
|
||||||
// Pass True, if a set of mask stickers should be created
|
|
||||||
ContainsMasks bool `json:"contains_masks,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for position where the mask should be
|
|
||||||
// placed on faces
|
|
||||||
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
AddStickerToSetParameters struct {
|
|
||||||
// User identifier of sticker set owner
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// Sticker set name
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. More info on Sending Files »
|
|
||||||
PNGSticker interface{} `json:"png_sticker"`
|
|
||||||
|
|
||||||
// One or more emoji corresponding to the sticker
|
|
||||||
Emojis string `json:"emojis"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for position where the mask should be placed on faces
|
|
||||||
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStickerPositionInSetParameters represents data for SetStickerPositionInSet
|
|
||||||
// method.
|
|
||||||
SetStickerPositionInSetParameters struct {
|
|
||||||
// File identifier of the sticker
|
|
||||||
Sticker string `json:"sticker"`
|
|
||||||
|
|
||||||
// New sticker position in the set, zero-based
|
|
||||||
Position int `json:"position"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteStickerFromSetParameters represents data for DeleteStickerFromSet method.
|
|
||||||
DeleteStickerFromSetParameters struct {
|
|
||||||
// File identifier of the sticker
|
|
||||||
Sticker string `json:"sticker"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// SendSticker send .webp stickers. On success, the sent Message is returned.
|
|
||||||
func (b *Bot) SendSticker(params *SendStickerParameters) (*Message, error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Set("chat_id", strconv.FormatInt(params.ChatID, 10))
|
|
||||||
args.Set("disable_notification", strconv.FormatBool(params.DisableNotification))
|
|
||||||
if params.ReplyToMessageID > 0 {
|
|
||||||
args.SetUint("reply_to_message_id", params.ReplyToMessageID)
|
|
||||||
}
|
|
||||||
if params.ReplyMarkup != nil {
|
|
||||||
rm, err := json.Marshal(params.ReplyMarkup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
args.SetBytesV("reply_markup", rm)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.Upload(MethodSendSticker, TypeSticker, "sticker", params.Sticker, args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var m Message
|
|
||||||
err = json.Unmarshal(*resp.Result, &m)
|
|
||||||
return &m, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStickerSet get a sticker set. On success, a StickerSet object is returned.
|
|
||||||
func (bot *Bot) GetStickerSet(name string) (set *StickerSet, err error) {
|
|
||||||
dst, err := json.Marshal(&GetStickerSetParameters{Name: name})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodGetStickerSet)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
set = new(StickerSet)
|
|
||||||
err = json.Unmarshal(*resp.Result, set)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UploadStickerFile upload a .png file with a sticker for later use in
|
|
||||||
// createNewStickerSet and addStickerToSet methods (can be used multiple times).
|
|
||||||
// Returns the uploaded File on success.
|
|
||||||
func (b *Bot) UploadStickerFile(userID int, pngSticker interface{}) (*File, error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.SetUint("user_id", userID)
|
|
||||||
|
|
||||||
resp, err := b.Upload(MethodUploadStickerFile, TypeSticker, "sticker", pngSticker, args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var f File
|
|
||||||
err = json.Unmarshal(*resp.Result, &f)
|
|
||||||
return &f, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateNewStickerSet create new sticker set owned by a user. The bot will be
|
|
||||||
// able to edit the created sticker set. Returns True on success.
|
|
||||||
func (b *Bot) CreateNewStickerSet(params *CreateNewStickerSetParameters) (ok bool, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.SetUint("user_id", params.UserID)
|
|
||||||
|
|
||||||
if !strings.HasSuffix(strings.ToLower(params.Name), strings.ToLower("_by_"+b.Username)) {
|
|
||||||
params.Name = params.Name + "_by_" + b.Username
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Set("name", params.Name)
|
|
||||||
args.Set("title", params.Title)
|
|
||||||
args.Set("emojis", params.Emojis)
|
|
||||||
args.Set("contains_masks", strconv.FormatBool(params.ContainsMasks))
|
|
||||||
|
|
||||||
if params.MaskPosition != nil {
|
|
||||||
mp, err := json.Marshal(params.MaskPosition)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
args.SetBytesV("mask_position", mp)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.Upload(MethodCreateNewStickerSet, TypeSticker, "sticker", params.PNGSticker, args)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddStickerToSet add a new sticker to a set created by the bot. Returns True
|
|
||||||
// on success.
|
|
||||||
func (b *Bot) AddStickerToSet(params *AddStickerToSetParameters) (ok bool, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.SetUint("user_id", params.UserID)
|
|
||||||
|
|
||||||
if !strings.HasSuffix(strings.ToLower(params.Name), strings.ToLower("_by_"+b.Username)) {
|
|
||||||
params.Name = params.Name + "_by_" + b.Username
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Set("emojis", params.Emojis)
|
|
||||||
|
|
||||||
if params.MaskPosition != nil {
|
|
||||||
mp, err := json.Marshal(params.MaskPosition)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
args.SetBytesV("mask_position", mp)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.Upload(MethodAddStickerToSet, TypeSticker, "sticker", params.PNGSticker, args)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStickerPositionInSet move a sticker in a set created by the bot to a
|
|
||||||
// specific position. Returns True on success.
|
|
||||||
func (b *Bot) SetStickerPositionInSet(sticker string, position int) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SetStickerPositionInSetParameters{
|
|
||||||
Sticker: sticker,
|
|
||||||
Position: position,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.request(dst, MethodSetStickerPositionInSet)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteStickerFromSet delete a sticker from a set created by the bot. Returns
|
|
||||||
// True on success.
|
|
||||||
func (bot *Bot) DeleteStickerFromSet(sticker string) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&DeleteStickerFromSetParameters{Sticker: sticker})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodDeleteStickerFromSet)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// PinChatMessageParameters represents data for PinChatMessage method.
|
// PinChatMessageParameters represents data for PinChatMessage method.
|
||||||
type PinChatMessageParameters struct {
|
type PinChatMessageParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -19,17 +17,18 @@ type PinChatMessageParameters struct {
|
||||||
// PinChatMessage pin a message in a supergroup or a channel. The bot must be an administrator in the
|
// PinChatMessage pin a message in a supergroup or a channel. The bot must be an administrator in the
|
||||||
// chat for this to work and must have the 'can_pin_messages' admin right in the supergroup or
|
// chat for this to work and must have the 'can_pin_messages' admin right in the supergroup or
|
||||||
// 'can_edit_messages' admin right in the channel. Returns True on success.
|
// 'can_edit_messages' admin right in the channel. Returns True on success.
|
||||||
func (bot *Bot) PinChatMessage(params *PinChatMessageParameters) (ok bool, err error) {
|
func (bot *Bot) PinChatMessage(params *PinChatMessageParameters) (bool, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodPinChatMessage)
|
resp, err := bot.request(dst, MethodPinChatMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
var ok bool
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
}
|
}
|
59
request.go
59
request.go
|
@ -1,59 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/kirillDanshin/dlog"
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultClient = new(http.Client)
|
|
||||||
|
|
||||||
func (bot *Bot) request(dst []byte, method string) (response *Response, err error) {
|
|
||||||
if bot.Client == nil {
|
|
||||||
bot.SetClient(defaultClient)
|
|
||||||
}
|
|
||||||
|
|
||||||
requestURI := http.AcquireURI()
|
|
||||||
requestURI.SetScheme("https")
|
|
||||||
requestURI.SetHost("api.telegram.org")
|
|
||||||
requestURI.SetPath(path.Join("bot"+bot.AccessToken, method))
|
|
||||||
|
|
||||||
req := http.AcquireRequest()
|
|
||||||
defer http.ReleaseRequest(req)
|
|
||||||
req.Header.SetContentType("application/json; charset=utf-8")
|
|
||||||
req.Header.SetMethod("POST")
|
|
||||||
if dst == nil {
|
|
||||||
req.Header.SetMethod("GET")
|
|
||||||
}
|
|
||||||
req.Header.SetRequestURI(requestURI.String())
|
|
||||||
req.Header.SetUserAgent(path.Join("telegram", strconv.FormatInt(Version, 10)))
|
|
||||||
req.Header.SetHostBytes(requestURI.Host())
|
|
||||||
req.SetBody(dst)
|
|
||||||
|
|
||||||
resp := http.AcquireResponse()
|
|
||||||
defer http.ReleaseResponse(resp)
|
|
||||||
|
|
||||||
err = bot.Client.Do(req, resp)
|
|
||||||
dlog.Ln("Request:")
|
|
||||||
dlog.D(req)
|
|
||||||
dlog.Ln("Response:")
|
|
||||||
dlog.D(resp)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
response = new(Response)
|
|
||||||
if err = json.Unmarshal(resp.Body(), response); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !response.Ok {
|
|
||||||
err = errors.New(response.Description)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -0,0 +1,796 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// SendAnimationParameters represents data for SendAnimation method.
|
||||||
|
SendAnimationParameters struct {
|
||||||
|
// Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data. More info on Sending Files »
|
||||||
|
Animation InputFile `json:"animation"`
|
||||||
|
|
||||||
|
// Duration of sent animation in seconds
|
||||||
|
Duration int `json:"duration,omitempty"`
|
||||||
|
|
||||||
|
// Animation width
|
||||||
|
Width int `json:"width,omitempty"`
|
||||||
|
|
||||||
|
// Animation height
|
||||||
|
Height int `json:"height,omitempty"`
|
||||||
|
|
||||||
|
// Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>. More info on Sending Files »
|
||||||
|
Thumb InputFile `json:"thumb,omitempty"`
|
||||||
|
|
||||||
|
// Animation caption (may also be used when resending animation by file_id), 0-200 characters
|
||||||
|
Caption string `json:"caption,omitempty"`
|
||||||
|
|
||||||
|
// Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption.
|
||||||
|
ParseMode string `json:"parse_mode,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendChatActionParameters represents data for SendChatAction method.
|
||||||
|
SendChatActionParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Type of action to broadcast
|
||||||
|
Action string `json:"action"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendContactParameters represents data for SendContact method.
|
||||||
|
SendContactParameters struct {
|
||||||
|
// Unique identifier for the target private chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Contact's phone number
|
||||||
|
PhoneNumber string `json:"phone_number"`
|
||||||
|
|
||||||
|
// Contact's first name
|
||||||
|
FirstName string `json:"first_name"`
|
||||||
|
|
||||||
|
// Contact's last name
|
||||||
|
LastName string `json:"last_name"`
|
||||||
|
|
||||||
|
// Additional data about the contact in the form of a vCard, 0-2048 bytes
|
||||||
|
VCard string `json:"vcard,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
||||||
|
// price' button will be shown. If not empty, the first button must be a Pay
|
||||||
|
// button.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendDocumentParameters represents data for SendDocument method.
|
||||||
|
SendDocumentParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// File to send. Pass a file_id as String to send a file that exists on the Telegram servers
|
||||||
|
// (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or
|
||||||
|
// upload a new one using multipart/form-data.
|
||||||
|
Document InputFile `json:"document"`
|
||||||
|
|
||||||
|
// Document caption (may also be used when resending documents by file_id), 0-200 characters
|
||||||
|
Caption string `json:"caption,omitempty"`
|
||||||
|
|
||||||
|
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
||||||
|
// fixed-width text or inline URLs in the media caption.
|
||||||
|
ParseMode string `json:"parse_mode,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply
|
||||||
|
// keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendInvoiceParameters represents data for SendInvoice method.
|
||||||
|
SendInvoiceParameters struct {
|
||||||
|
// Unique identifier for the target private chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Product name, 1-32 characters
|
||||||
|
Title string `json:"title"`
|
||||||
|
|
||||||
|
// Product description, 1-255 characters
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to
|
||||||
|
// the user, use for your internal processes.
|
||||||
|
Payload string `json:"payload"`
|
||||||
|
|
||||||
|
// Payments provider token, obtained via Botfather
|
||||||
|
ProviderToken string `json:"provider_token"`
|
||||||
|
|
||||||
|
// Unique deep-linking parameter that can be used to generate this invoice
|
||||||
|
// when used as a start parameter
|
||||||
|
StartParameter string `json:"start_parameter"`
|
||||||
|
|
||||||
|
// Three-letter ISO 4217 currency code, see more on currencies
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
|
||||||
|
// JSON-encoded data about the invoice, which will be shared with the payment
|
||||||
|
// provider. A detailed description of required fields should be provided by
|
||||||
|
// the payment provider.
|
||||||
|
ProviderData string `json:"provider_data,omitempty"`
|
||||||
|
|
||||||
|
// URL of the product photo for the invoice. Can be a photo of the goods or a
|
||||||
|
// marketing image for a service. People like it better when they see what
|
||||||
|
// they are paying for.
|
||||||
|
PhotoURL string `json:"photo_url,omitempty"`
|
||||||
|
|
||||||
|
// Price breakdown, a list of components (e.g. product price, tax, discount,
|
||||||
|
// delivery cost, delivery tax, bonus, etc.)
|
||||||
|
Prices []LabeledPrice `json:"prices"`
|
||||||
|
|
||||||
|
// Photo size
|
||||||
|
PhotoSize int `json:"photo_size,omitempty"`
|
||||||
|
|
||||||
|
// Photo width
|
||||||
|
PhotoWidth int `json:"photo_width,omitempty"`
|
||||||
|
|
||||||
|
// Photo height
|
||||||
|
PhotoHeight int `json:"photo_height,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if you require the user's full name to complete the order
|
||||||
|
NeedName bool `json:"need_name,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if you require the user's phone number to complete the order
|
||||||
|
NeedPhoneNumber bool `json:"need_phone_number,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if you require the user's email to complete the order
|
||||||
|
NeedEmail bool `json:"need_email,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if you require the user's shipping address to complete the
|
||||||
|
// order
|
||||||
|
NeedShippingAddress bool `json:"need_shipping_address,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if the final price depends on the shipping method
|
||||||
|
IsFlexible bool `json:"is_flexible,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
||||||
|
// price' button will be shown. If not empty, the first button must be a Pay
|
||||||
|
// button.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendLocationParameters represents data for SendLocation method.
|
||||||
|
SendLocationParameters struct {
|
||||||
|
// Unique identifier for the target private chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Latitude of the location
|
||||||
|
Latitude float32 `json:"latitude"`
|
||||||
|
|
||||||
|
// Longitude of the location
|
||||||
|
Longitude float32 `json:"longitude"`
|
||||||
|
|
||||||
|
// Period in seconds for which the location will be updated (see Live
|
||||||
|
// Locations), should be between 60 and 86400.
|
||||||
|
LivePeriod int `json:"live_period,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
||||||
|
// price' button will be shown. If not empty, the first button must be a Pay
|
||||||
|
// button.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMediaGroupParameters represents data for SendMediaGroup method.
|
||||||
|
SendMediaGroupParameters struct {
|
||||||
|
// Unique identifier for the target chat.
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// A JSON-serialized array describing photos and videos to be sent, must
|
||||||
|
// include 2–10 items
|
||||||
|
Media []interface{} `json:"media"`
|
||||||
|
|
||||||
|
// Sends the messages silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the messages are a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessageParameters represents data for SendMessage method.
|
||||||
|
SendMessageParameters struct {
|
||||||
|
// Unique identifier for the target chat or username of the target channel
|
||||||
|
// (in the format @channelusername)
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Text of the message to be sent
|
||||||
|
Text string `json:"text"`
|
||||||
|
|
||||||
|
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
||||||
|
// fixed-width text or inline URLs in your bot's message.
|
||||||
|
ParseMode string `json:"parse_mode,omitempty"`
|
||||||
|
|
||||||
|
// Disables link previews for links in this message
|
||||||
|
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an inline
|
||||||
|
// keyboard, custom reply keyboard, instructions to remove reply keyboard or
|
||||||
|
// to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPhotoParameters represents data for SendPhoto method.
|
||||||
|
SendPhotoParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Photo to send. Pass a file_id as String to send a photo that exists on the
|
||||||
|
// Telegram servers (recommended), pass an HTTP URL as a String for Telegram
|
||||||
|
// to get a photo from the Internet, or upload a new photo using
|
||||||
|
// multipart/form-data.
|
||||||
|
Photo InputFile `json:"photo"`
|
||||||
|
|
||||||
|
// Photo caption (may also be used when resending photos by file_id), 0-200
|
||||||
|
// characters
|
||||||
|
Caption string `json:"caption,omitempty"`
|
||||||
|
|
||||||
|
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
||||||
|
// fixed-width text or inline URLs in the media caption.
|
||||||
|
ParseMode string `json:"parse_mode,omitempty"`
|
||||||
|
|
||||||
|
// Disables link previews for links in this message
|
||||||
|
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an inline
|
||||||
|
// keyboard, custom reply keyboard, instructions to remove reply keyboard or
|
||||||
|
// to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
SendPollConfig struct {
|
||||||
|
// Unique identifier for the target chat. A native poll can't be sent to a private chat.
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Poll question, 1-255 characters
|
||||||
|
Question string `json:"question"`
|
||||||
|
|
||||||
|
// List of answer options, 2-10 strings 1-100 characters each
|
||||||
|
Options []string `json:"options"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard,
|
||||||
|
// instructions to remove reply keyboard or to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendVenueParameters represents data for SendVenue method.
|
||||||
|
SendVenueParameters struct {
|
||||||
|
// Unique identifier for the target private chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Latitude of the venue
|
||||||
|
Latitude float32 `json:"latitude"`
|
||||||
|
|
||||||
|
// Longitude of the venue
|
||||||
|
Longitude float32 `json:"longitude"`
|
||||||
|
|
||||||
|
// Name of the venue
|
||||||
|
Title string `json:"title"`
|
||||||
|
|
||||||
|
// Address of the venue
|
||||||
|
Address string `json:"address"`
|
||||||
|
|
||||||
|
// Foursquare identifier of the venue
|
||||||
|
FoursquareID string `json:"foursquare_id,omitempty"`
|
||||||
|
|
||||||
|
// Foursquare type of the venue, if known. (For example,
|
||||||
|
// "arts_entertainment/default", "arts_entertainment/aquarium" or
|
||||||
|
// "food/icecream".)
|
||||||
|
FoursquareType string `json:"foursquare_type,omitempty"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
||||||
|
// price' button will be shown. If not empty, the first button must be a Pay
|
||||||
|
// button.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendGameParameters represents data for SendGame method.
|
||||||
|
SendGameParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Short name of the game, serves as the unique identifier for the game. Set
|
||||||
|
// up your games via Botfather.
|
||||||
|
GameShortName string `json:"game_short_name"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification with no
|
||||||
|
// sound.
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// A JSON-serialized object for an inline keyboard. If empty, one ‘Play
|
||||||
|
// game_title’ button will be shown. If not empty, the first button must
|
||||||
|
// launch the game.
|
||||||
|
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendStickerParameters represents data for SetSticker method.
|
||||||
|
SendStickerParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Sticker to send
|
||||||
|
Sticker interface{} `json:"sticker"`
|
||||||
|
|
||||||
|
// Sends the message silently. Users will receive a notification
|
||||||
|
// with no sound
|
||||||
|
DisableNotification bool `json:"disable_notification,omitempty"`
|
||||||
|
|
||||||
|
// If the message is a reply, ID of the original message
|
||||||
|
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
||||||
|
|
||||||
|
// Additional interface options. A JSON-serialized object for an
|
||||||
|
// inline keyboard, custom reply keyboard, instructions to remove
|
||||||
|
// reply keyboard or to force a reply from the user.
|
||||||
|
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewAnimation creates SendAnimationParameters only with required parameters.
|
||||||
|
func NewAnimation(chatID int64, animation interface{}) *SendAnimationParameters {
|
||||||
|
return &SendAnimationParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Animation: animation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContact creates SendContactParameters only with required parameters.
|
||||||
|
func NewContact(chatID int64, phoneNumber, firstName string) *SendContactParameters {
|
||||||
|
return &SendContactParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
PhoneNumber: phoneNumber,
|
||||||
|
FirstName: firstName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDocument creates SendDocumentParameters only with required parameters.
|
||||||
|
func NewDocument(chatID int64, document interface{}) *SendDocumentParameters {
|
||||||
|
return &SendDocumentParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Document: document,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInvoice creates SendInvoiceParameters only with required parameters.
|
||||||
|
func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices ...LabeledPrice) *SendInvoiceParameters {
|
||||||
|
return &SendInvoiceParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Title: title,
|
||||||
|
Description: description,
|
||||||
|
Payload: payload,
|
||||||
|
ProviderToken: providerToken,
|
||||||
|
StartParameter: startParameter,
|
||||||
|
Currency: currency,
|
||||||
|
Prices: prices,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocation creates SendLocationParameters only with required parameters.
|
||||||
|
func NewLocation(chatID int64, latitude, longitude float32) *SendLocationParameters {
|
||||||
|
return &SendLocationParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMediaGroup creates SendMediaGroupParameters only with required parameters.
|
||||||
|
func NewMediaGroup(chatID int64, media ...interface{}) *SendMediaGroupParameters {
|
||||||
|
return &SendMediaGroupParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Media: media,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessage creates SendMessageParameters only with required parameters.
|
||||||
|
func NewMessage(chatID int64, text string) *SendMessageParameters {
|
||||||
|
return &SendMessageParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPhoto creates SendPhotoParameters only with required parameters.
|
||||||
|
func NewPhoto(chatID int64, photo interface{}) *SendPhotoParameters {
|
||||||
|
return &SendPhotoParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Photo: photo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPoll(chatID int64, question string, options ...string) SendPollConfig {
|
||||||
|
return SendPollConfig{
|
||||||
|
ChatID: chatID,
|
||||||
|
Question: question,
|
||||||
|
Options: options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVenue creates SendVenueParameters only with required parameters.
|
||||||
|
func NewVenue(chatID int64, latitude, longitude float32, title, address string) *SendVenueParameters {
|
||||||
|
return &SendVenueParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
Title: title,
|
||||||
|
Address: address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGame creates SendGameParameters only with required parameters.
|
||||||
|
func NewGame(chatID int64, gameShortName string) *SendGameParameters {
|
||||||
|
return &SendGameParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
GameShortName: gameShortName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendAnimation send animation files (GIF or H.264/MPEG-4 AVC video without
|
||||||
|
// sound). On success, the sent Message is returned. Bots can currently send
|
||||||
|
// animation files of up to 50 MB in size, this limit may be changed in the
|
||||||
|
// future.
|
||||||
|
func (bot *Bot) SendAnimation(params *SendAnimationParameters) (*Message, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
||||||
|
|
||||||
|
if params.Caption != "" {
|
||||||
|
args.Add("caption", params.Caption)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyMarkup != nil {
|
||||||
|
dst, err := parser.Marshal(params.ReplyMarkup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args.Add("reply_markup", string(dst))
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyToMessageID != 0 {
|
||||||
|
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
||||||
|
|
||||||
|
resp, err := bot.Upload(MethodSendAnimation, "animation", "", params.Animation, args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &result)
|
||||||
|
return &result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendChatAction tell the user that something is happening on the bot's side.
|
||||||
|
// The status is set for 5 seconds or less (when a message arrives from your bot,
|
||||||
|
// Telegram clients clear its typing status). Returns True on success.
|
||||||
|
//
|
||||||
|
// We only recommend using this method when a response from the bot will take a
|
||||||
|
// noticeable amount of time to arrive.
|
||||||
|
func (bot *Bot) SendChatAction(chatID int64, action string) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SendChatActionParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Action: action,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendChatAction)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendContact send phone contacts. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendContact(params *SendContactParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(*params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendContact)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendDocument send general files. On success, the sent Message is returned. Bots can currently send
|
||||||
|
// files of any type of up to 50 MB in size, this limit may be changed in the future.
|
||||||
|
func (bot *Bot) SendDocument(params *SendDocumentParameters) (*Message, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
||||||
|
|
||||||
|
if params.Caption != "" {
|
||||||
|
args.Add("caption", params.Caption)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyMarkup != nil {
|
||||||
|
dst, err := parser.Marshal(params.ReplyMarkup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args.Add("reply_markup", string(dst))
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyToMessageID != 0 {
|
||||||
|
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
||||||
|
|
||||||
|
resp, err := bot.Upload(MethodSendDocument, "document", "", params.Document, args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &result)
|
||||||
|
return &result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendInvoice send invoices. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendInvoice(params *SendInvoiceParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendInvoice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendLocation send point on the map. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendLocation(params *SendLocationParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMediaGroup send a group of photos or videos as an album. On success, an array of the sent
|
||||||
|
// Messages is returned.
|
||||||
|
func (bot *Bot) SendMediaGroup(params *SendMediaGroupParameters) ([]Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendMediaGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var group []Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &group)
|
||||||
|
return group, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessage send text messages. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendMessage(params *SendMessageParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendMessage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPhoto send photos. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendPhoto(params *SendPhotoParameters) (*Message, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
||||||
|
|
||||||
|
if params.Caption != "" {
|
||||||
|
args.Add("caption", params.Caption)
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyMarkup != nil {
|
||||||
|
dst, err := parser.Marshal(params.ReplyMarkup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args.Add("reply_markup", string(dst))
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.ReplyToMessageID != 0 {
|
||||||
|
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
||||||
|
|
||||||
|
resp, err := bot.Upload(MethodSendPhoto, "photo", "", params.Photo, args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &result)
|
||||||
|
return &result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPoll send a native poll. A native poll can't be sent to a private chat. On success, the sent Message is
|
||||||
|
// returned.
|
||||||
|
func (b *Bot) SendPoll(params SendPollConfig) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.request(dst, MethodSendPoll)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendVenue send information about a venue. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendVenue(params *SendVenueParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendVenue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendGame send a game. On success, the sent Message is returned.
|
||||||
|
func (bot *Bot) SendGame(params *SendGameParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSendGame)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendSticker send .webp stickers. On success, the sent Message is returned.
|
||||||
|
func (b *Bot) SendSticker(params *SendStickerParameters) (*Message, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Set("chat_id", strconv.FormatInt(params.ChatID, 10))
|
||||||
|
args.Set("disable_notification", strconv.FormatBool(params.DisableNotification))
|
||||||
|
if params.ReplyToMessageID > 0 {
|
||||||
|
args.SetUint("reply_to_message_id", params.ReplyToMessageID)
|
||||||
|
}
|
||||||
|
if params.ReplyMarkup != nil {
|
||||||
|
rm, err := parser.Marshal(params.ReplyMarkup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
args.SetBytesV("reply_markup", rm)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.Upload(MethodSendSticker, TypeSticker, "sticker", params.Sticker, args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &result)
|
||||||
|
return &result, err
|
||||||
|
}
|
|
@ -1,89 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SendAnimationParameters represents data for SendAnimation method.
|
|
||||||
type SendAnimationParameters struct {
|
|
||||||
// Unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data. More info on Sending Files »
|
|
||||||
Animation InputFile `json:"animation"`
|
|
||||||
|
|
||||||
// Duration of sent animation in seconds
|
|
||||||
Duration int `json:"duration,omitempty"`
|
|
||||||
|
|
||||||
// Animation width
|
|
||||||
Width int `json:"width,omitempty"`
|
|
||||||
|
|
||||||
// Animation height
|
|
||||||
Height int `json:"height,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 90. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can’t be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>. More info on Sending Files »
|
|
||||||
Thumb InputFile `json:"thumb,omitempty"`
|
|
||||||
|
|
||||||
// Animation caption (may also be used when resending animation by file_id), 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAnimation creates SendAnimationParameters only with required parameters.
|
|
||||||
func NewAnimation(chatID int64, animation interface{}) *SendAnimationParameters {
|
|
||||||
return &SendAnimationParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Animation: animation,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendAnimation send animation files (GIF or H.264/MPEG-4 AVC video without
|
|
||||||
// sound). On success, the sent Message is returned. Bots can currently send
|
|
||||||
// animation files of up to 50 MB in size, this limit may be changed in the
|
|
||||||
// future.
|
|
||||||
func (bot *Bot) SendAnimation(params *SendAnimationParameters) (msg *Message, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
|
||||||
|
|
||||||
if params.Caption != "" {
|
|
||||||
args.Add("caption", params.Caption)
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyMarkup != nil {
|
|
||||||
dst, err := json.Marshal(params.ReplyMarkup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
args.Add("reply_markup", string(dst))
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyToMessageID != 0 {
|
|
||||||
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
|
||||||
|
|
||||||
resp, err := bot.Upload(MethodSendAnimation, "animation", "", params.Animation, args)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendChatActionParameters represents data for SendChatAction method.
|
|
||||||
type SendChatActionParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Type of action to broadcast
|
|
||||||
Action string `json:"action"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendChatAction tell the user that something is happening on the bot's side.
|
|
||||||
// The status is set for 5 seconds or less (when a message arrives from your bot,
|
|
||||||
// Telegram clients clear its typing status). Returns True on success.
|
|
||||||
//
|
|
||||||
// We only recommend using this method when a response from the bot will take a
|
|
||||||
// noticeable amount of time to arrive.
|
|
||||||
func (bot *Bot) SendChatAction(chatID int64, action string) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SendChatActionParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Action: action,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendChatAction)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendContactParameters represents data for SendContact method.
|
|
||||||
type SendContactParameters struct {
|
|
||||||
// Unique identifier for the target private chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Contact's phone number
|
|
||||||
PhoneNumber string `json:"phone_number"`
|
|
||||||
|
|
||||||
// Contact's first name
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
|
|
||||||
// Contact's last name
|
|
||||||
LastName string `json:"last_name"`
|
|
||||||
|
|
||||||
// Additional data about the contact in the form of a vCard, 0-2048 bytes
|
|
||||||
VCard string `json:"vcard,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
|
||||||
// price' button will be shown. If not empty, the first button must be a Pay
|
|
||||||
// button.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewContact creates SendContactParameters only with required parameters.
|
|
||||||
func NewContact(chatID int64, phoneNumber, firstName string) *SendContactParameters {
|
|
||||||
return &SendContactParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
PhoneNumber: phoneNumber,
|
|
||||||
FirstName: firstName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendContact send phone contacts. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendContact(params *SendContactParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(*params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendContact)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SendDocumentParameters represents data for SendDocument method.
|
|
||||||
type SendDocumentParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// File to send. Pass a file_id as String to send a file that exists on the Telegram servers
|
|
||||||
// (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or
|
|
||||||
// upload a new one using multipart/form-data.
|
|
||||||
Document InputFile `json:"document"`
|
|
||||||
|
|
||||||
// Document caption (may also be used when resending documents by file_id), 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply
|
|
||||||
// keyboard, instructions to remove reply keyboard or to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDocument creates SendDocumentParameters only with required parameters.
|
|
||||||
func NewDocument(chatID int64, document interface{}) *SendDocumentParameters {
|
|
||||||
return &SendDocumentParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Document: document,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendDocument send general files. On success, the sent Message is returned. Bots can currently send
|
|
||||||
// files of any type of up to 50 MB in size, this limit may be changed in the future.
|
|
||||||
func (bot *Bot) SendDocument(params *SendDocumentParameters) (msg *Message, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
|
||||||
|
|
||||||
if params.Caption != "" {
|
|
||||||
args.Add("caption", params.Caption)
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyMarkup != nil {
|
|
||||||
dst, err := json.Marshal(params.ReplyMarkup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
args.Add("reply_markup", string(dst))
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyToMessageID != 0 {
|
|
||||||
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
|
||||||
|
|
||||||
resp, err := bot.Upload(MethodSendDocument, "document", "", params.Document, args)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
111
send_invoice.go
111
send_invoice.go
|
@ -1,111 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendInvoiceParameters represents data for SendInvoice method.
|
|
||||||
type SendInvoiceParameters struct {
|
|
||||||
// Unique identifier for the target private chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Product name, 1-32 characters
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Product description, 1-255 characters
|
|
||||||
Description string `json:"description"`
|
|
||||||
|
|
||||||
// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to
|
|
||||||
// the user, use for your internal processes.
|
|
||||||
Payload string `json:"payload"`
|
|
||||||
|
|
||||||
// Payments provider token, obtained via Botfather
|
|
||||||
ProviderToken string `json:"provider_token"`
|
|
||||||
|
|
||||||
// Unique deep-linking parameter that can be used to generate this invoice
|
|
||||||
// when used as a start parameter
|
|
||||||
StartParameter string `json:"start_parameter"`
|
|
||||||
|
|
||||||
// Three-letter ISO 4217 currency code, see more on currencies
|
|
||||||
Currency string `json:"currency"`
|
|
||||||
|
|
||||||
// JSON-encoded data about the invoice, which will be shared with the payment
|
|
||||||
// provider. A detailed description of required fields should be provided by
|
|
||||||
// the payment provider.
|
|
||||||
ProviderData string `json:"provider_data,omitempty"`
|
|
||||||
|
|
||||||
// URL of the product photo for the invoice. Can be a photo of the goods or a
|
|
||||||
// marketing image for a service. People like it better when they see what
|
|
||||||
// they are paying for.
|
|
||||||
PhotoURL string `json:"photo_url,omitempty"`
|
|
||||||
|
|
||||||
// Price breakdown, a list of components (e.g. product price, tax, discount,
|
|
||||||
// delivery cost, delivery tax, bonus, etc.)
|
|
||||||
Prices []LabeledPrice `json:"prices"`
|
|
||||||
|
|
||||||
// Photo size
|
|
||||||
PhotoSize int `json:"photo_size,omitempty"`
|
|
||||||
|
|
||||||
// Photo width
|
|
||||||
PhotoWidth int `json:"photo_width,omitempty"`
|
|
||||||
|
|
||||||
// Photo height
|
|
||||||
PhotoHeight int `json:"photo_height,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if you require the user's full name to complete the order
|
|
||||||
NeedName bool `json:"need_name,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if you require the user's phone number to complete the order
|
|
||||||
NeedPhoneNumber bool `json:"need_phone_number,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if you require the user's email to complete the order
|
|
||||||
NeedEmail bool `json:"need_email,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if you require the user's shipping address to complete the
|
|
||||||
// order
|
|
||||||
NeedShippingAddress bool `json:"need_shipping_address,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if the final price depends on the shipping method
|
|
||||||
IsFlexible bool `json:"is_flexible,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
|
||||||
// price' button will be shown. If not empty, the first button must be a Pay
|
|
||||||
// button.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInvoice creates SendInvoiceParameters only with required parameters.
|
|
||||||
func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices ...LabeledPrice) *SendInvoiceParameters {
|
|
||||||
return &SendInvoiceParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Title: title,
|
|
||||||
Description: description,
|
|
||||||
Payload: payload,
|
|
||||||
ProviderToken: providerToken,
|
|
||||||
StartParameter: startParameter,
|
|
||||||
Currency: currency,
|
|
||||||
Prices: prices,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendInvoice send invoices. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendInvoice(params *SendInvoiceParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendInvoice)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendLocationParameters represents data for SendLocation method.
|
|
||||||
type SendLocationParameters struct {
|
|
||||||
// Unique identifier for the target private chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Latitude of the location
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of the location
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// Period in seconds for which the location will be updated (see Live
|
|
||||||
// Locations), should be between 60 and 86400.
|
|
||||||
LivePeriod int `json:"live_period,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
|
||||||
// price' button will be shown. If not empty, the first button must be a Pay
|
|
||||||
// button.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLocation creates SendLocationParameters only with required parameters.
|
|
||||||
func NewLocation(chatID int64, latitude, longitude float32) *SendLocationParameters {
|
|
||||||
return &SendLocationParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Latitude: latitude,
|
|
||||||
Longitude: longitude,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendLocation send point on the map. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendLocation(params *SendLocationParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendLocation)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendMediaGroupParameters represents data for SendMediaGroup method.
|
|
||||||
type SendMediaGroupParameters struct {
|
|
||||||
// Unique identifier for the target chat.
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// A JSON-serialized array describing photos and videos to be sent, must
|
|
||||||
// include 2–10 items
|
|
||||||
Media []interface{} `json:"media"`
|
|
||||||
|
|
||||||
// Sends the messages silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the messages are a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMediaGroup creates SendMediaGroupParameters only with required parameters.
|
|
||||||
func NewMediaGroup(chatID int64, media ...interface{}) *SendMediaGroupParameters {
|
|
||||||
return &SendMediaGroupParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Media: media,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMediaGroup send a group of photos or videos as an album. On success, an array of the sent
|
|
||||||
// Messages is returned.
|
|
||||||
func (bot *Bot) SendMediaGroup(params *SendMediaGroupParameters) (album []Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendMediaGroup)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &album)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendMessageParameters represents data for SendMessage method.
|
|
||||||
type SendMessageParameters struct {
|
|
||||||
// Unique identifier for the target chat or username of the target channel
|
|
||||||
// (in the format @channelusername)
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Text of the message to be sent
|
|
||||||
Text string `json:"text"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in your bot's message.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Disables link previews for links in this message
|
|
||||||
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an inline
|
|
||||||
// keyboard, custom reply keyboard, instructions to remove reply keyboard or
|
|
||||||
// to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMessage creates SendMessageParameters only with required parameters.
|
|
||||||
func NewMessage(chatID int64, text string) *SendMessageParameters {
|
|
||||||
return &SendMessageParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Text: text,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMessage send text messages. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendMessage(params *SendMessageParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendMessage)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SendPhotoParameters represents data for SendPhoto method.
|
|
||||||
type SendPhotoParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Photo to send. Pass a file_id as String to send a photo that exists on the
|
|
||||||
// Telegram servers (recommended), pass an HTTP URL as a String for Telegram
|
|
||||||
// to get a photo from the Internet, or upload a new photo using
|
|
||||||
// multipart/form-data.
|
|
||||||
Photo InputFile `json:"photo"`
|
|
||||||
|
|
||||||
// Photo caption (may also be used when resending photos by file_id), 0-200
|
|
||||||
// characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Disables link previews for links in this message
|
|
||||||
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an inline
|
|
||||||
// keyboard, custom reply keyboard, instructions to remove reply keyboard or
|
|
||||||
// to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPhoto creates SendPhotoParameters only with required parameters.
|
|
||||||
func NewPhoto(chatID int64, photo interface{}) *SendPhotoParameters {
|
|
||||||
return &SendPhotoParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Photo: photo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendPhoto send photos. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendPhoto(params *SendPhotoParameters) (msg *Message, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Add("chat_id", strconv.FormatInt(params.ChatID, 10))
|
|
||||||
|
|
||||||
if params.Caption != "" {
|
|
||||||
args.Add("caption", params.Caption)
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyMarkup != nil {
|
|
||||||
dst, err := json.Marshal(params.ReplyMarkup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
args.Add("reply_markup", string(dst))
|
|
||||||
}
|
|
||||||
|
|
||||||
if params.ReplyToMessageID != 0 {
|
|
||||||
args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID))
|
|
||||||
}
|
|
||||||
|
|
||||||
args.Add("disable_notification", strconv.FormatBool(params.DisableNotification))
|
|
||||||
|
|
||||||
resp, err := bot.Upload(MethodSendPhoto, "photo", "", params.Photo, args)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
50
send_poll.go
50
send_poll.go
|
@ -1,50 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
type SendPollConfig struct {
|
|
||||||
// Unique identifier for the target chat. A native poll can't be sent to a private chat.
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Poll question, 1-255 characters
|
|
||||||
Question string `json:"question"`
|
|
||||||
|
|
||||||
// List of answer options, 2-10 strings 1-100 characters each
|
|
||||||
Options []string `json:"options"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard,
|
|
||||||
// instructions to remove reply keyboard or to force a reply from the user.
|
|
||||||
ReplyMarkup interface{} `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPoll(chatID int64, question string, options ...string) SendPollConfig {
|
|
||||||
return SendPollConfig{
|
|
||||||
ChatID: chatID,
|
|
||||||
Question: question,
|
|
||||||
Options: options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendPoll send a native poll. A native poll can't be sent to a private chat. On success, the sent Message is
|
|
||||||
// returned.
|
|
||||||
func (b *Bot) SendPoll(params SendPollConfig) (*Message, error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.request(dst, MethodSendPoll)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var msg Message
|
|
||||||
err = json.Unmarshal(*resp.Result, &msg)
|
|
||||||
return &msg, err
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SendVenueParameters represents data for SendVenue method.
|
|
||||||
type SendVenueParameters struct {
|
|
||||||
// Unique identifier for the target private chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Latitude of the venue
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of the venue
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// Name of the venue
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Address of the venue
|
|
||||||
Address string `json:"address"`
|
|
||||||
|
|
||||||
// Foursquare identifier of the venue
|
|
||||||
FoursquareID string `json:"foursquare_id,omitempty"`
|
|
||||||
|
|
||||||
// Foursquare type of the venue, if known. (For example,
|
|
||||||
// "arts_entertainment/default", "arts_entertainment/aquarium" or
|
|
||||||
// "food/icecream".)
|
|
||||||
FoursquareType string `json:"foursquare_type,omitempty"`
|
|
||||||
|
|
||||||
// Sends the message silently. Users will receive a notification with no
|
|
||||||
// sound.
|
|
||||||
DisableNotification bool `json:"disable_notification,omitempty"`
|
|
||||||
|
|
||||||
// If the message is a reply, ID of the original message
|
|
||||||
ReplyToMessageID int `json:"reply_to_message_id,omitempty"`
|
|
||||||
|
|
||||||
// A JSON-serialized object for an inline keyboard. If empty, one 'Pay total
|
|
||||||
// price' button will be shown. If not empty, the first button must be a Pay
|
|
||||||
// button.
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewVenue creates SendVenueParameters only with required parameters.
|
|
||||||
func NewVenue(chatID int64, latitude, longitude float32, title, address string) *SendVenueParameters {
|
|
||||||
return &SendVenueParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Latitude: latitude,
|
|
||||||
Longitude: longitude,
|
|
||||||
Title: title,
|
|
||||||
Address: address,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendVenue send information about a venue. On success, the sent Message is returned.
|
|
||||||
func (bot *Bot) SendVenue(params *SendVenueParameters) (msg *Message, err error) {
|
|
||||||
dst, err := json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSendVenue)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = new(Message)
|
|
||||||
err = json.Unmarshal(*resp.Result, msg)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -0,0 +1,343 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// SetChatDescriptionParameters represents data for SetChatDescription method.
|
||||||
|
SetChatDescriptionParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// New chat description, 0-255 characters
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatPhotoParameters represents data for SetChatPhoto method.
|
||||||
|
SetChatPhotoParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// New chat photo, uploaded using multipart/form-data
|
||||||
|
ChatPhoto interface{} `json:"chat_photo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatStickerSetParameters represents data for SetChatStickerSet method.
|
||||||
|
SetChatStickerSetParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// Name of the sticker set to be set as the group sticker set
|
||||||
|
StickerSetName string `json:"sticker_set_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatTitleParameters represents data for SetChatTitle method.
|
||||||
|
SetChatTitleParameters struct {
|
||||||
|
// Unique identifier for the target chat
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
|
||||||
|
// New chat title, 1-255 characters
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPassportDataErrorsParameters struct {
|
||||||
|
// User identifier
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// A JSON-serialized array describing the errors
|
||||||
|
Errors []PassportElementError `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWebhookParameters represents data for SetWebhook method.
|
||||||
|
SetWebhookParameters struct {
|
||||||
|
// HTTPS url to send updates to. Use an empty string to remove webhook
|
||||||
|
// integration
|
||||||
|
URL string `json:"url"`
|
||||||
|
|
||||||
|
// Upload your public key certificate so that the root certificate in use can
|
||||||
|
// be checked. See our self-signed guide for details.
|
||||||
|
Certificate InputFile `json:"certificate,omitempty"`
|
||||||
|
|
||||||
|
// Maximum allowed number of simultaneous HTTPS connections to the webhook
|
||||||
|
// for update delivery, 1-100. Defaults to 40. Use lower values to limit the
|
||||||
|
// load on your bot‘s server, and higher values to increase your bot’s
|
||||||
|
// throughput.
|
||||||
|
MaxConnections int `json:"max_connections,omitempty"`
|
||||||
|
|
||||||
|
// List the types of updates you want your bot to receive. For example,
|
||||||
|
// specify [“message”, “edited_channel_post”, “callback_query”] to only
|
||||||
|
// receive updates of these types. See Update for a complete list of
|
||||||
|
// available update types. Specify an empty list to receive all updates
|
||||||
|
// regardless of type (default). If not specified, the previous setting will
|
||||||
|
// be used.
|
||||||
|
//
|
||||||
|
// Please note that this parameter doesn't affect updates created before the
|
||||||
|
// call to the setWebhook, so unwanted updates may be received for a short
|
||||||
|
// period of time.
|
||||||
|
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGameScoreParameters represents data for SetGameScore method.
|
||||||
|
SetGameScoreParameters struct {
|
||||||
|
// User identifier
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// New score, must be non-negative
|
||||||
|
Score int `json:"score"`
|
||||||
|
|
||||||
|
// Required if inline_message_id is not specified. Identifier of the sent
|
||||||
|
// message
|
||||||
|
MessageID int `json:"message_id,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if the high score is allowed to decrease. This can be useful
|
||||||
|
// when fixing mistakes or banning cheaters
|
||||||
|
Force bool `json:"force,omitempty"`
|
||||||
|
|
||||||
|
// Pass True, if the game message should not be automatically edited to
|
||||||
|
// include the current scoreboard
|
||||||
|
DisableEditMessage bool `json:"disable_edit_message,omitempty"`
|
||||||
|
|
||||||
|
// Required if inline_message_id is not specified. Unique identifier for the
|
||||||
|
// target chat
|
||||||
|
ChatID int64 `json:"chat_id,omitempty"`
|
||||||
|
|
||||||
|
// Required if chat_id and message_id are not specified. Identifier of the
|
||||||
|
// inline message
|
||||||
|
InlineMessageID string `json:"inline_message_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStickerPositionInSetParameters represents data for SetStickerPositionInSet
|
||||||
|
// method.
|
||||||
|
SetStickerPositionInSetParameters struct {
|
||||||
|
// File identifier of the sticker
|
||||||
|
Sticker string `json:"sticker"`
|
||||||
|
|
||||||
|
// New sticker position in the set, zero-based
|
||||||
|
Position int `json:"position"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewWebhook creates new SetWebhookParameters only with required parameters.
|
||||||
|
func NewWebhook(url string, file interface{}) *SetWebhookParameters {
|
||||||
|
return &SetWebhookParameters{
|
||||||
|
URL: url,
|
||||||
|
Certificate: file,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGameScore creates SetGameScoreParameters only with required parameters.
|
||||||
|
func NewGameScore(userID, score int) *SetGameScoreParameters {
|
||||||
|
return &SetGameScoreParameters{
|
||||||
|
UserID: userID,
|
||||||
|
Score: score,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatDescription change the description of a supergroup or a channel. The
|
||||||
|
// bot must be an administrator in the chat for this to work and must have the
|
||||||
|
// appropriate admin rights. Returns True on success.
|
||||||
|
func (bot *Bot) SetChatDescription(chatID int64, description string) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SetChatDescriptionParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Description: description,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSetChatDescription)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatPhoto set a new profile photo for the chat. Photos can't be changed for private chats. The
|
||||||
|
// bot must be an administrator in the chat for this to work and must have the appropriate admin
|
||||||
|
// rights. Returns True on success.
|
||||||
|
//
|
||||||
|
// Note: In regular groups (non-supergroups), this method will only work if the 'All Members Are
|
||||||
|
// Admins' setting is off in the target group.
|
||||||
|
func (bot *Bot) SetChatPhoto(chatID int64, chatPhoto interface{}) (bool, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Add("chat_id", strconv.FormatInt(chatID, 10))
|
||||||
|
|
||||||
|
resp, err := bot.Upload(MethodSetChatPhoto, TypePhoto, "chat_photo", chatPhoto, args)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatStickerSet set a new group sticker set for a supergroup. The bot must be an administrator
|
||||||
|
// in the chat for this to work and must have the appropriate admin rights. Use the field
|
||||||
|
// can_set_sticker_set optionally returned in getChat requests to check if the bot can use this
|
||||||
|
// method. Returns True on success.
|
||||||
|
func (bot *Bot) SetChatStickerSet(chatID int64, stickerSetName string) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SetChatStickerSetParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
StickerSetName: stickerSetName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSetChatStickerSet)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetChatTitle change the title of a chat. Titles can't be changed for private
|
||||||
|
// chats. The bot must be an administrator in the chat for this to work and must
|
||||||
|
// have the appropriate admin rights. Returns True on success.
|
||||||
|
//
|
||||||
|
// Note: In regular groups (non-supergroups), this method will only work if the
|
||||||
|
// 'All Members Are Admins' setting is off in the target group.
|
||||||
|
func (bot *Bot) SetChatTitle(chatID int64, title string) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SetChatTitleParameters{
|
||||||
|
ChatID: chatID,
|
||||||
|
Title: title,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSetChatTitle)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPassportDataErrors informs a user that some of the Telegram Passport
|
||||||
|
// elements they provided contains errors. The user will not be able to re-submit
|
||||||
|
// their Passport to you until the errors are fixed (the contents of the field
|
||||||
|
// for which you returned the error must change). Returns True on success.
|
||||||
|
//
|
||||||
|
// Use this if the data submitted by the user doesn't satisfy the standards your
|
||||||
|
// service requires for any reason. For example, if a birthday date seems
|
||||||
|
// invalid, a submitted document is blurry, a scan shows evidence of tampering,
|
||||||
|
// etc. Supply some details in the error message to make sure the user knows how
|
||||||
|
// to correct the issues.
|
||||||
|
func (b *Bot) SetPassportDataErrors(userId int, errors []PassportElementError) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SetPassportDataErrorsParameters{
|
||||||
|
UserID: userId,
|
||||||
|
Errors: errors,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.request(dst, MethodSetPassportDataErrors)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWebhook specify a url and receive incoming updates via an outgoing webhook.
|
||||||
|
// Whenever there is an update for the bot, we will send an HTTPS POST request to
|
||||||
|
// the specified url, containing a JSON-serialized Update. In case of an
|
||||||
|
// unsuccessful request, we will give up after a reasonable amount of attempts.
|
||||||
|
// Returns true.
|
||||||
|
//
|
||||||
|
// If you'd like to make sure that the Webhook request comes from Telegram, we
|
||||||
|
// recommend using a secret path in the URL, e.g. https://www.example.com/<token>.
|
||||||
|
// Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
|
||||||
|
func (bot *Bot) SetWebhook(params *SetWebhookParameters) (bool, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.Add("url", params.URL)
|
||||||
|
|
||||||
|
if len(params.AllowedUpdates) > 0 {
|
||||||
|
args.Add("allowed_updates", strings.Join(params.AllowedUpdates, ","))
|
||||||
|
}
|
||||||
|
if params.MaxConnections > 0 &&
|
||||||
|
params.MaxConnections <= 100 {
|
||||||
|
args.Add("max_connections", strconv.Itoa(params.MaxConnections))
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp *Response
|
||||||
|
var err error
|
||||||
|
if params.Certificate != nil {
|
||||||
|
resp, err = bot.Upload(MethodSetWebhook, "certificate", "cert.pem", params.Certificate, args)
|
||||||
|
} else {
|
||||||
|
var dst []byte
|
||||||
|
dst, err = parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err = bot.request(dst, MethodSetWebhook)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGameScore set the score of the specified user in a game. On success, if the
|
||||||
|
// message was sent by the bot, returns the edited Message, otherwise returns
|
||||||
|
// True. Returns an error, if the new score is not greater than the user's
|
||||||
|
// current score in the chat and force is False.
|
||||||
|
func (bot *Bot) SetGameScore(params *SetGameScoreParameters) (*Message, error) {
|
||||||
|
dst, err := parser.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := bot.request(dst, MethodSetGameScore)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg Message
|
||||||
|
err = parser.Unmarshal(resp.Result, &msg)
|
||||||
|
return &msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStickerPositionInSet move a sticker in a set created by the bot to a
|
||||||
|
// specific position. Returns True on success.
|
||||||
|
func (b *Bot) SetStickerPositionInSet(sticker string, position int) (bool, error) {
|
||||||
|
dst, err := parser.Marshal(&SetStickerPositionInSetParameters{
|
||||||
|
Sticker: sticker,
|
||||||
|
Position: position,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := b.request(dst, MethodSetStickerPositionInSet)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SetChatDescriptionParameters represents data for SetChatDescription method.
|
|
||||||
type SetChatDescriptionParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// New chat description, 0-255 characters
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChatDescription change the description of a supergroup or a channel. The
|
|
||||||
// bot must be an administrator in the chat for this to work and must have the
|
|
||||||
// appropriate admin rights. Returns True on success.
|
|
||||||
func (bot *Bot) SetChatDescription(chatID int64, description string) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SetChatDescriptionParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Description: description,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSetChatDescription)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetChatPhotoParameters represents data for SetChatPhoto method.
|
|
||||||
type SetChatPhotoParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// New chat photo, uploaded using multipart/form-data
|
|
||||||
ChatPhoto interface{} `json:"chat_photo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChatPhoto set a new profile photo for the chat. Photos can't be changed for private chats. The
|
|
||||||
// bot must be an administrator in the chat for this to work and must have the appropriate admin
|
|
||||||
// rights. Returns True on success.
|
|
||||||
//
|
|
||||||
// Note: In regular groups (non-supergroups), this method will only work if the 'All Members Are
|
|
||||||
// Admins' setting is off in the target group.
|
|
||||||
func (bot *Bot) SetChatPhoto(chatID int64, chatPhoto interface{}) (ok bool, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Add("chat_id", strconv.FormatInt(chatID, 10))
|
|
||||||
|
|
||||||
resp, err := bot.Upload(MethodSetChatPhoto, TypePhoto, "chat_photo", chatPhoto, args)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SetChatStickerSetParameters represents data for SetChatStickerSet method.
|
|
||||||
type SetChatStickerSetParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// Name of the sticker set to be set as the group sticker set
|
|
||||||
StickerSetName string `json:"sticker_set_name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChatStickerSet set a new group sticker set for a supergroup. The bot must be an administrator
|
|
||||||
// in the chat for this to work and must have the appropriate admin rights. Use the field
|
|
||||||
// can_set_sticker_set optionally returned in getChat requests to check if the bot can use this
|
|
||||||
// method. Returns True on success.
|
|
||||||
func (bot *Bot) SetChatStickerSet(chatID int64, stickerSetName string) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SetChatStickerSetParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
StickerSetName: stickerSetName,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSetChatStickerSet)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// SetChatTitleParameters represents data for SetChatTitle method.
|
|
||||||
type SetChatTitleParameters struct {
|
|
||||||
// Unique identifier for the target chat
|
|
||||||
ChatID int64 `json:"chat_id"`
|
|
||||||
|
|
||||||
// New chat title, 1-255 characters
|
|
||||||
Title string `json:"title"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChatTitle change the title of a chat. Titles can't be changed for private
|
|
||||||
// chats. The bot must be an administrator in the chat for this to work and must
|
|
||||||
// have the appropriate admin rights. Returns True on success.
|
|
||||||
//
|
|
||||||
// Note: In regular groups (non-supergroups), this method will only work if the
|
|
||||||
// 'All Members Are Admins' setting is off in the target group.
|
|
||||||
func (bot *Bot) SetChatTitle(chatID int64, title string) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SetChatTitleParameters{
|
|
||||||
ChatID: chatID,
|
|
||||||
Title: title,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodSetChatTitle)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
type SetPassportDataErrorsParameters struct {
|
|
||||||
// User identifier
|
|
||||||
UserID int `json:"user_id"`
|
|
||||||
|
|
||||||
// A JSON-serialized array describing the errors
|
|
||||||
Errors []PassportElementError `json:"errors"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPassportDataErrors informs a user that some of the Telegram Passport
|
|
||||||
// elements they provided contains errors. The user will not be able to re-submit
|
|
||||||
// their Passport to you until the errors are fixed (the contents of the field
|
|
||||||
// for which you returned the error must change). Returns True on success.
|
|
||||||
//
|
|
||||||
// Use this if the data submitted by the user doesn't satisfy the standards your
|
|
||||||
// service requires for any reason. For example, if a birthday date seems
|
|
||||||
// invalid, a submitted document is blurry, a scan shows evidence of tampering,
|
|
||||||
// etc. Supply some details in the error message to make sure the user knows how
|
|
||||||
// to correct the issues.
|
|
||||||
func (b *Bot) SetPassportDataErrors(userId int, errors []PassportElementError) (ok bool, err error) {
|
|
||||||
dst, err := json.Marshal(&SetPassportDataErrorsParameters{
|
|
||||||
UserID: userId,
|
|
||||||
Errors: errors,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := b.request(dst, MethodSetPassportDataErrors)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetWebhookParameters represents data for SetWebhook method.
|
|
||||||
type SetWebhookParameters struct {
|
|
||||||
// HTTPS url to send updates to. Use an empty string to remove webhook
|
|
||||||
// integration
|
|
||||||
URL string `json:"url"`
|
|
||||||
|
|
||||||
// Upload your public key certificate so that the root certificate in use can
|
|
||||||
// be checked. See our self-signed guide for details.
|
|
||||||
Certificate InputFile `json:"certificate,omitempty"`
|
|
||||||
|
|
||||||
// Maximum allowed number of simultaneous HTTPS connections to the webhook
|
|
||||||
// for update delivery, 1-100. Defaults to 40. Use lower values to limit the
|
|
||||||
// load on your bot‘s server, and higher values to increase your bot’s
|
|
||||||
// throughput.
|
|
||||||
MaxConnections int `json:"max_connections,omitempty"`
|
|
||||||
|
|
||||||
// List the types of updates you want your bot to receive. For example,
|
|
||||||
// specify [“message”, “edited_channel_post”, “callback_query”] to only
|
|
||||||
// receive updates of these types. See Update for a complete list of
|
|
||||||
// available update types. Specify an empty list to receive all updates
|
|
||||||
// regardless of type (default). If not specified, the previous setting will
|
|
||||||
// be used.
|
|
||||||
//
|
|
||||||
// Please note that this parameter doesn't affect updates created before the
|
|
||||||
// call to the setWebhook, so unwanted updates may be received for a short
|
|
||||||
// period of time.
|
|
||||||
AllowedUpdates []string `json:"allowed_updates,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWebhook creates new SetWebhookParameters only with required parameters.
|
|
||||||
func NewWebhook(url string, file interface{}) *SetWebhookParameters {
|
|
||||||
return &SetWebhookParameters{
|
|
||||||
URL: url,
|
|
||||||
Certificate: file,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetWebhook specify a url and receive incoming updates via an outgoing webhook.
|
|
||||||
// Whenever there is an update for the bot, we will send an HTTPS POST request to
|
|
||||||
// the specified url, containing a JSON-serialized Update. In case of an
|
|
||||||
// unsuccessful request, we will give up after a reasonable amount of attempts.
|
|
||||||
// Returns true.
|
|
||||||
//
|
|
||||||
// If you'd like to make sure that the Webhook request comes from Telegram, we
|
|
||||||
// recommend using a secret path in the URL, e.g. https://www.example.com/<token>.
|
|
||||||
// Since nobody else knows your bot‘s token, you can be pretty sure it’s us.
|
|
||||||
func (bot *Bot) SetWebhook(params *SetWebhookParameters) (ok bool, err error) {
|
|
||||||
args := http.AcquireArgs()
|
|
||||||
defer http.ReleaseArgs(args)
|
|
||||||
args.Add("url", params.URL)
|
|
||||||
|
|
||||||
if len(params.AllowedUpdates) > 0 {
|
|
||||||
args.Add("allowed_updates", strings.Join(params.AllowedUpdates, ","))
|
|
||||||
}
|
|
||||||
if params.MaxConnections > 0 &&
|
|
||||||
params.MaxConnections <= 100 {
|
|
||||||
args.Add("max_connections", strconv.Itoa(params.MaxConnections))
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp *Response
|
|
||||||
if params.Certificate != nil {
|
|
||||||
resp, err = bot.Upload(MethodSetWebhook, "certificate", "cert.pem", params.Certificate, args)
|
|
||||||
} else {
|
|
||||||
var dst []byte
|
|
||||||
dst, err = json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err = bot.request(dst, MethodSetWebhook)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
type StopPollConfig struct {
|
type StopPollConfig struct {
|
||||||
// Unique identifier for the target chat. A native poll can't be sent to a private chat.
|
// Unique identifier for the target chat. A native poll can't be sent to a private chat.
|
||||||
ChatID int64 `json:"chat_id"`
|
ChatID int64 `json:"chat_id"`
|
||||||
|
@ -14,7 +12,7 @@ type StopPollConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bot) StopPoll(params StopPollConfig) (*Poll, error) {
|
func (b *Bot) StopPoll(params StopPollConfig) (*Poll, error) {
|
||||||
dst, err := json.Marshal(params)
|
dst, err := parser.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -25,6 +23,6 @@ func (b *Bot) StopPoll(params StopPollConfig) (*Poll, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var poll Poll
|
var poll Poll
|
||||||
err = json.Unmarshal(*resp.Result, &poll)
|
err = parser.Unmarshal(resp.Result, &poll)
|
||||||
return &poll, err
|
return &poll, err
|
||||||
}
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
gojson "encoding/json"
|
||||||
|
"errors"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
json "github.com/json-iterator/go"
|
||||||
|
http "github.com/valyala/fasthttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Response represents a response from the Telegram API with the result
|
||||||
|
// stored raw. If ok equals true, the request was successful, and the result
|
||||||
|
// of the query can be found in the result field. In case of an unsuccessful
|
||||||
|
// request, ok equals false, and the error is explained in the error field.
|
||||||
|
type Response struct {
|
||||||
|
Ok bool `json:"ok"`
|
||||||
|
ErrorCode int `json:"error_code,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Result gojson.RawMessage `json:"result,omitempty"`
|
||||||
|
Parameters *ResponseParameters `json:"parameters,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultClient = http.Client{}
|
||||||
|
parser = json.ConfigFastest
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Bot) request(dst []byte, method string) (*Response, error) {
|
||||||
|
if b.Client == nil {
|
||||||
|
b.SetClient(&defaultClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
requestURI := http.AcquireURI()
|
||||||
|
requestURI.SetScheme("https")
|
||||||
|
requestURI.SetHost("api.telegram.org")
|
||||||
|
requestURI.SetPath(path.Join("bot"+b.AccessToken, method))
|
||||||
|
|
||||||
|
req := http.AcquireRequest()
|
||||||
|
defer http.ReleaseRequest(req)
|
||||||
|
req.Header.SetContentType("application/json; charset=utf-8")
|
||||||
|
req.Header.SetMethod(http.MethodPost)
|
||||||
|
if dst == nil {
|
||||||
|
req.Header.SetMethod(http.MethodGet)
|
||||||
|
}
|
||||||
|
req.Header.SetRequestURI(requestURI.String())
|
||||||
|
req.Header.SetUserAgent(path.Join("telegram", Version))
|
||||||
|
req.Header.SetHostBytes(requestURI.Host())
|
||||||
|
req.SetBody(dst)
|
||||||
|
|
||||||
|
resp := http.AcquireResponse()
|
||||||
|
defer http.ReleaseResponse(resp)
|
||||||
|
|
||||||
|
if err := b.Client.Do(req, resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var data Response
|
||||||
|
if err := parser.Unmarshal(resp.Body(), &data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !data.Ok {
|
||||||
|
return nil, errors.New(data.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
tg "gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
var bot = new(tg.Bot)
|
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
photoURL = http.AcquireURI()
|
|
||||||
defer http.ReleaseURI(photoURL)
|
|
||||||
|
|
||||||
photoURL.SetScheme("https")
|
|
||||||
photoURL.SetHost("simg3.gelbooru.com")
|
|
||||||
photoURL.SetPath(path.Join("images", "46", "24", "46246c1b8c4fcc37050085a850c165c4.jpg"))
|
|
||||||
|
|
||||||
bot.AccessToken = os.Getenv("BOT_ACCESS_TOKEN")
|
|
||||||
os.Exit(m.Run())
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
chatID = 76918703
|
|
||||||
superGroupID = -1001120141283
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSendChatAction(t *testing.T) {
|
|
||||||
ok, err := bot.SendChatAction(chatID, telegram.ActionTyping)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func TestKickChatMember(t *testing.T) {
|
|
||||||
ok, err := bot.KickChatMember(&telegram.KickChatMemberParameters{
|
|
||||||
ChatID: superGroupID,
|
|
||||||
UserID: chatID,
|
|
||||||
UntilDate: time.Now().Add(time.Second * 30).Unix(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnbanChatMember(t *testing.T) {
|
|
||||||
ok, err := bot.UnbanChatMember(superGroupID, chatID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func TestExportChatInviteLink(t *testing.T) {
|
|
||||||
inviteLink, err := bot.ExportChatInviteLink(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
t.Log("InviteLink:", inviteLink)
|
|
||||||
if inviteLink == "" {
|
|
||||||
t.Error("unexpected result: inviteLink is empty")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetChatPhoto(t *testing.T) {
|
|
||||||
ok, err := bot.SetChatPhoto(superGroupID, "./photo.png")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteChatPhoto(t *testing.T) {
|
|
||||||
ok, err := bot.DeleteChatPhoto(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetChatTitle(t *testing.T) {
|
|
||||||
ok, err := bot.SetChatTitle(superGroupID, "Go Telegram Bot API")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetChatDescription(t *testing.T) {
|
|
||||||
ok, err := bot.SetChatDescription(
|
|
||||||
superGroupID,
|
|
||||||
fmt.Sprint("Go Telegram BotAPI testing chat (", time.Now().Unix(), ")"),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPinChatMessage(t *testing.T) {
|
|
||||||
ok, err := bot.PinChatMessage(&telegram.PinChatMessageParameters{
|
|
||||||
ChatID: superGroupID,
|
|
||||||
MessageID: replyToMessageID,
|
|
||||||
DisableNotification: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnpinChatMessage(t *testing.T) {
|
|
||||||
ok, err := bot.UnpinChatMessage(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func TestLeaveChat(t *testing.T) {
|
|
||||||
ErrNotMember := "Forbidden: bot is not a member of the supergroup chat"
|
|
||||||
ok, err := bot.LeaveChat(-1001037355946)
|
|
||||||
if err != nil &&
|
|
||||||
err.Error() != ErrNotMember {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok &&
|
|
||||||
err.Error() != ErrNotMember {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func TestGetChat(t *testing.T) {
|
|
||||||
chat, err := bot.GetChat(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if chat == nil {
|
|
||||||
t.Error("unexpected result: chat is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetChatAdministrators(t *testing.T) {
|
|
||||||
admins, err := bot.GetChatAdministrators(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if len(admins) <= 0 {
|
|
||||||
t.Error("unexpected result: admins not exist")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetChatMembersCount(t *testing.T) {
|
|
||||||
total, err := bot.GetChatMembersCount(superGroupID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
t.Log(total, "members")
|
|
||||||
if total <= 0 {
|
|
||||||
t.Error("unexpected result: members count is 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetChatMember(t *testing.T) {
|
|
||||||
member, err := bot.GetChatMember(superGroupID, chatID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if member == nil {
|
|
||||||
t.Error("unexpected result: member is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetChatStickerSet(t *testing.T) {
|
|
||||||
ErrCantSetStickerSet := "Bad Request: can't set supergroup sticker set"
|
|
||||||
ok, err := bot.SetChatStickerSet(superGroupID, "HentaiDB")
|
|
||||||
if err != nil &&
|
|
||||||
err.Error() != ErrCantSetStickerSet {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok &&
|
|
||||||
err.Error() != ErrCantSetStickerSet {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteChatStickerSet(t *testing.T) {
|
|
||||||
ErrCantSetStickerSet := "Bad Request: can't set supergroup sticker set"
|
|
||||||
ok, err := bot.DeleteChatStickerSet(superGroupID)
|
|
||||||
if err != nil &&
|
|
||||||
err.Error() != ErrCantSetStickerSet {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok &&
|
|
||||||
err.Error() != ErrCantSetStickerSet {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetMe(t *testing.T) {
|
|
||||||
var err error
|
|
||||||
bot.User, err = bot.GetMe()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if bot.User == nil {
|
|
||||||
t.Error("unexpected result: bot user is nil")
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetUserProfilePhotos(t *testing.T) {
|
|
||||||
photos, err := bot.GetUserProfilePhotos(&telegram.GetUserProfilePhotosParameters{
|
|
||||||
UserID: chatID,
|
|
||||||
Offset: 0,
|
|
||||||
Limit: 100,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if photos == nil {
|
|
||||||
t.Error("unexpected result: photos is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetFile(t *testing.T) {
|
|
||||||
file, err := bot.GetFile(documentFileID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if file == nil {
|
|
||||||
t.Error("unexpected result: file is nil")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
const replyToMessageID = 35
|
|
||||||
|
|
||||||
func TestSendMessage(t *testing.T) {
|
|
||||||
resp, err := bot.SendMessage(
|
|
||||||
telegram.NewMessage(chatID, "Hello, World"),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestForwardMessage(t *testing.T) {
|
|
||||||
resp, err := bot.ForwardMessage(
|
|
||||||
telegram.NewForwardMessage(chatID, superGroupID, replyToMessageID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEditMessageText(t *testing.T) {
|
|
||||||
text := telegram.NewMessageText(
|
|
||||||
fmt.Sprint("Go Telegram BotAPI testing chat (", time.Now().Unix(), ")"),
|
|
||||||
)
|
|
||||||
text.ChatID = chatID
|
|
||||||
text.MessageID = replyToMessageID
|
|
||||||
resp, err := bot.EditMessageText(text)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: resp is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEditMessageCaption(t *testing.T) {
|
|
||||||
var caption telegram.EditMessageCaptionParameters
|
|
||||||
caption.Caption = fmt.Sprint("Go Telegram BotAPI testing chat (", time.Now().Unix(), ")")
|
|
||||||
caption.ChatID = chatID
|
|
||||||
caption.MessageID = messageID
|
|
||||||
resp, err := bot.EditMessageCaption(&caption)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: resp is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEditMessageReplyMarkup(t *testing.T) {
|
|
||||||
var markup telegram.EditMessageReplyMarkupParameters
|
|
||||||
markup.ChatID = superGroupID
|
|
||||||
markup.MessageID = replyToMessageID
|
|
||||||
markup.ReplyMarkup = telegram.NewInlineKeyboardMarkup(
|
|
||||||
telegram.NewInlineKeyboardRow(
|
|
||||||
telegram.NewInlineKeyboardButton(
|
|
||||||
"hello",
|
|
||||||
fmt.Sprint(time.Now().Unix()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
resp, err := bot.EditMessageReplyMarkup(&markup)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: resp is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteMessage(t *testing.T) {
|
|
||||||
ok, err := bot.DeleteMessage(chatID, messageID)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
BIN
test/photo.png
BIN
test/photo.png
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
|
@ -1,101 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
tg "gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
photoFileID = "AgADAgADw6cxG4zHKAkr42N7RwEN3IFShCoABHQwXEtVks4EH2wBAAEC"
|
|
||||||
documentFileID = "BQADAgADOQADjMcoCcioX1GrDvp3Ag"
|
|
||||||
// audioFileID = "BQADAgADRgADjMcoCdXg3lSIN49lAg"
|
|
||||||
// voiceFileID = "AwADAgADWQADjMcoCeul6r_q52IyAg"
|
|
||||||
// videoFileID = "BAADAgADZgADjMcoCav432kYe0FRAg"
|
|
||||||
// videoNoteFileID = "DQADAgADdQAD70cQSUK41dLsRMqfAg"
|
|
||||||
// stickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
photoURL *http.URI
|
|
||||||
messageID int
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSendPhoto(t *testing.T) {
|
|
||||||
resp, err := bot.SendPhoto(
|
|
||||||
tg.NewPhoto(chatID, photoFileID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
} else {
|
|
||||||
messageID = resp.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendDocument(t *testing.T) {
|
|
||||||
resp, err := bot.SendDocument(
|
|
||||||
tg.NewDocument(chatID, documentFileID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendMediaGroup(t *testing.T) {
|
|
||||||
resp, err := bot.SendMediaGroup(
|
|
||||||
tg.NewMediaGroup(
|
|
||||||
chatID,
|
|
||||||
tg.NewInputMediaPhoto(photoFileID),
|
|
||||||
tg.NewInputMediaPhoto(photoURL.String()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if len(resp) <= 0 {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendLocation(t *testing.T) {
|
|
||||||
resp, err := bot.SendLocation(
|
|
||||||
tg.NewLocation(chatID, 36.724510, 139.268181),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: resp is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendVenue(t *testing.T) {
|
|
||||||
resp, err := bot.SendVenue(
|
|
||||||
tg.NewVenue(chatID, 36.724510, 139.268181, "Japan", "Japan"),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: resp is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSendContact(t *testing.T) {
|
|
||||||
resp, err := bot.SendContact(
|
|
||||||
tg.NewContact(chatID, "+42410", "Telegram"),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if resp == nil {
|
|
||||||
t.Error("unexpected result: message is nil")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestGetUpdates(t *testing.T) {
|
|
||||||
updates, err := bot.GetUpdates(nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if len(updates) <= 0 {
|
|
||||||
t.Error("unexpected result: no updates")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gitlab.com/toby3d/telegram"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSetWebhook(t *testing.T) {
|
|
||||||
ok, err := bot.SetWebhook(
|
|
||||||
telegram.NewWebhook("https://toby3d.ru/telegram", nil),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteWebhook(t *testing.T) {
|
|
||||||
ok, err := bot.DeleteWebhook()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
t.Error("unexpected result: ok is not true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetWebhookInfo(t *testing.T) {
|
|
||||||
info, err := bot.GetWebhookInfo()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err.Error())
|
|
||||||
}
|
|
||||||
if info == nil {
|
|
||||||
t.Error("unexpected result: info is nil")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Game represents a game. Use BotFather to create and edit games, their
|
|
||||||
// short names will act as unique identifiers.
|
|
||||||
Game struct {
|
|
||||||
// Title of the game
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Description of the game
|
|
||||||
Description string `json:"description"`
|
|
||||||
|
|
||||||
// Brief description of the game or high scores included in the game
|
|
||||||
// message. Can be automatically edited to include current high scores
|
|
||||||
// for the game when the bot calls setGameScore, or manually edited
|
|
||||||
// using editMessageText. 0-4096 characters.
|
|
||||||
Text string `json:"text,omitempty"`
|
|
||||||
|
|
||||||
// Photo that will be displayed in the game message in chats.
|
|
||||||
Photo []PhotoSize `json:"photo"`
|
|
||||||
|
|
||||||
// Special entities that appear in text, such as usernames, URLs, bot
|
|
||||||
// commands, etc.
|
|
||||||
TextEntities []MessageEntity `json:"text_entities,omitempty"`
|
|
||||||
|
|
||||||
// Animation that will be displayed in the game message in chats. Upload
|
|
||||||
// via BotFather
|
|
||||||
Animation *Animation `json:"animation,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// CallbackGame a placeholder, currently holds no information. Use BotFather
|
|
||||||
// to set up your game.
|
|
||||||
CallbackGame struct{}
|
|
||||||
|
|
||||||
// GameHighScore represents one row of the high scores table for a game.
|
|
||||||
GameHighScore struct {
|
|
||||||
// Position in high score table for the game
|
|
||||||
Position int `json:"position"`
|
|
||||||
|
|
||||||
// Score
|
|
||||||
Score int `json:"score"`
|
|
||||||
|
|
||||||
// User
|
|
||||||
User *User `json:"user"`
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,840 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
type (
|
|
||||||
// InlineQuery represents an incoming inline query. When the user sends an
|
|
||||||
// empty query, your bot could return some default or trending results.
|
|
||||||
InlineQuery struct {
|
|
||||||
// Unique identifier for this query
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Text of the query (up to 512 characters)
|
|
||||||
Query string `json:"query"`
|
|
||||||
|
|
||||||
// Offset of the results to be returned, can be controlled by the bot
|
|
||||||
Offset string `json:"offset"`
|
|
||||||
|
|
||||||
// Sender
|
|
||||||
From *User `json:"from"`
|
|
||||||
|
|
||||||
// Sender location, only for bots that request user location
|
|
||||||
Location *Location `json:"location,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResult represents one result of an inline query.
|
|
||||||
InlineQueryResult interface {
|
|
||||||
ResultID() string
|
|
||||||
ResultType() string
|
|
||||||
ResultReplyMarkup() *InlineKeyboardMarkup
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultArticle represents a link to an article or web page.
|
|
||||||
InlineQueryResultArticle struct {
|
|
||||||
// Type of the result, must be article
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 Bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Title of the result
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// URL of the result
|
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Url of the thumbnail for the result
|
|
||||||
ThumbURL string `json:"thumb_url,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent
|
|
||||||
InputMessageContent interface{} `json:"input_message_content"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Pass True, if you don't want the URL to be shown in the message
|
|
||||||
HideURL bool `json:"hide_url,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail width
|
|
||||||
ThumbWidth int `json:"thumb_width,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail height
|
|
||||||
ThumbHeight int `json:"thumb_height,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultPhoto represents a link to a photo. By default, this
|
|
||||||
// photo will be sent by the user with optional caption. Alternatively, you
|
|
||||||
// can use input_message_content to send a message with the specified content
|
|
||||||
// instead of the photo.
|
|
||||||
InlineQueryResultPhoto struct {
|
|
||||||
// Type of the result, must be photo
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL of the photo. Photo must be in jpeg format. Photo size
|
|
||||||
// must not exceed 5MB
|
|
||||||
PhotoURL string `json:"photo_url"`
|
|
||||||
|
|
||||||
// URL of the thumbnail for the photo
|
|
||||||
ThumbURL string `json:"thumb_url"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the photo to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Width of the photo
|
|
||||||
PhotoWidth int `json:"photo_width,omitempty"`
|
|
||||||
|
|
||||||
// Height of the photo
|
|
||||||
PhotoHeight int `json:"photo_height,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the photo
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultGif represents a link to an animated GIF file. By
|
|
||||||
// default, this animated GIF file will be sent by the user with optional
|
|
||||||
// caption. Alternatively, you can use input_message_content to send a
|
|
||||||
// message with the specified content instead of the animation.
|
|
||||||
InlineQueryResultGif struct {
|
|
||||||
// Type of the result, must be gif
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL for the GIF file. File size must not exceed 1MB
|
|
||||||
GifURL string `json:"gif_url"`
|
|
||||||
|
|
||||||
// URL of the static thumbnail for the result (jpeg or gif)
|
|
||||||
ThumbURL string `json:"thumb_url"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the GIF file to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Width of the GIF
|
|
||||||
GifWidth int `json:"gif_width,omitempty"`
|
|
||||||
|
|
||||||
// Height of the GIF
|
|
||||||
GifHeight int `json:"gif_height,omitempty"`
|
|
||||||
|
|
||||||
// Duration of the GIF
|
|
||||||
GifDuration int `json:"gif_duration,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the GIF animation
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultMpeg4Gif represents a link to a video animation
|
|
||||||
// (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4
|
|
||||||
// file will be sent by the user with optional caption. Alternatively, you
|
|
||||||
// can use input_message_content to send a message with the specified content
|
|
||||||
// instead of the animation.
|
|
||||||
InlineQueryResultMpeg4Gif struct {
|
|
||||||
// Type of the result, must be mpeg4_gif
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL for the MP4 file. File size must not exceed 1MB
|
|
||||||
Mpeg4URL string `json:"mpeg4_url"`
|
|
||||||
|
|
||||||
// URL of the static thumbnail (jpeg or gif) for the result
|
|
||||||
ThumbURL string `json:"thumb_url"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the MPEG-4 file to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Video width
|
|
||||||
Mpeg4Width int `json:"mpeg4_width,omitempty"`
|
|
||||||
|
|
||||||
// Video height
|
|
||||||
Mpeg4Height int `json:"mpeg4_height,omitempty"`
|
|
||||||
|
|
||||||
// Video duration
|
|
||||||
Mpeg4Duration int `json:"mpeg4_duration,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the video animation
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultVideo represents a link to a page containing an embedded
|
|
||||||
// video player or a video file. By default, this video file will be sent by
|
|
||||||
// the user with an optional caption. Alternatively, you can use
|
|
||||||
// input_message_content to send a message with the specified content
|
|
||||||
// instead of the video.
|
|
||||||
//
|
|
||||||
// If an InlineQueryResultVideo message contains an embedded video (e.g.,
|
|
||||||
// YouTube), you must replace its content using input_message_content.
|
|
||||||
InlineQueryResultVideo struct {
|
|
||||||
// Type of the result, must be video
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL for the embedded video player or video file
|
|
||||||
VideoURL string `json:"video_url"`
|
|
||||||
|
|
||||||
// Mime type of the content of video url, "text/html" or "video/mp4"
|
|
||||||
MimeType string `json:"mime_type"`
|
|
||||||
|
|
||||||
// URL of the thumbnail (jpeg only) for the video
|
|
||||||
ThumbURL string `json:"thumb_url"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Caption of the video to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Video width
|
|
||||||
VideoWidth int `json:"video_width,omitempty"`
|
|
||||||
|
|
||||||
// Video height
|
|
||||||
VideoHeight int `json:"video_height,omitempty"`
|
|
||||||
|
|
||||||
// Video duration in seconds
|
|
||||||
VideoDuration int `json:"video_duration,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the video. This field is
|
|
||||||
// required if InlineQueryResultVideo is used to send an HTML-page as a
|
|
||||||
// result (e.g., a YouTube video).
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultAudio represents a link to an mp3 audio file. By default,
|
|
||||||
// this audio file will be sent by the user. Alternatively, you can use
|
|
||||||
// input_message_content to send a message with the specified content
|
|
||||||
// instead of the audio.
|
|
||||||
InlineQueryResultAudio struct {
|
|
||||||
// Type of the result, must be audio
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL for the audio file
|
|
||||||
AudioURL string `json:"audio_url"`
|
|
||||||
|
|
||||||
// Title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Caption, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Performer
|
|
||||||
Performer string `json:"performer,omitempty"`
|
|
||||||
|
|
||||||
// Audio duration in seconds
|
|
||||||
AudioDuration int `json:"audio_duration,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the audio
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultVoice represents a link to a voice recording in an .ogg
|
|
||||||
// container encoded with OPUS. By default, this voice recording will be
|
|
||||||
// sent by the user. Alternatively, you can use input_message_content to
|
|
||||||
// send a message with the specified content instead of the the voice message.
|
|
||||||
InlineQueryResultVoice struct {
|
|
||||||
// Type of the result, must be voice
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid URL for the voice recording
|
|
||||||
VoiceURL string `json:"voice_url"`
|
|
||||||
|
|
||||||
// Recording title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Caption, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Recording duration in seconds
|
|
||||||
VoiceDuration int `json:"voice_duration,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the voice recording
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultDocument represents a link to a file. By default, this
|
|
||||||
// file will be sent by the user with an optional caption. Alternatively,
|
|
||||||
// you can use input_message_content to send a message with the specified
|
|
||||||
// content instead of the file. Currently, only .PDF and .ZIP files can be
|
|
||||||
// sent using this method.
|
|
||||||
InlineQueryResultDocument struct {
|
|
||||||
// Type of the result, must be document
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Caption of the document to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// A valid URL for the file
|
|
||||||
DocumentURL string `json:"document_url"`
|
|
||||||
|
|
||||||
// Mime type of the content of the file, either "application/pdf" or
|
|
||||||
// "application/zip"
|
|
||||||
MimeType string `json:"mime_type"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// URL of the thumbnail (jpeg only) for the file
|
|
||||||
ThumbURL string `json:"thumb_url,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the file
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail width
|
|
||||||
ThumbWidth int `json:"thumb_width,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail height
|
|
||||||
ThumbHeight int `json:"thumb_height,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultLocation represents a location on a map. By default, the
|
|
||||||
// location will be sent by the user. Alternatively, you can use
|
|
||||||
// input_message_content to send a message with the specified content
|
|
||||||
// instead of the location.
|
|
||||||
InlineQueryResultLocation struct {
|
|
||||||
// Type of the result, must be location
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 Bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Location title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Url of the thumbnail for the result
|
|
||||||
ThumbURL string `json:"thumb_url,omitempty"`
|
|
||||||
|
|
||||||
// Location latitude in degrees
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Location longitude in degrees
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the location
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail width
|
|
||||||
ThumbWidth int `json:"thumb_width,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail height
|
|
||||||
ThumbHeight int `json:"thumb_height,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultVenue represents a venue. By default, the venue will be
|
|
||||||
// sent by the user. Alternatively, you can use input_message_content to
|
|
||||||
// send a message with the specified content instead of the venue.
|
|
||||||
InlineQueryResultVenue struct {
|
|
||||||
// Type of the result, must be venue
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 Bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Title of the venue
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Address of the venue
|
|
||||||
Address string `json:"address"`
|
|
||||||
|
|
||||||
// Foursquare identifier of the venue if known
|
|
||||||
FoursquareID string `json:"foursquare_id,omitempty"`
|
|
||||||
|
|
||||||
// Foursquare type of the venue, if known. (For example,
|
|
||||||
// "arts_entertainment/default", "arts_entertainment/aquarium" or
|
|
||||||
// "food/icecream".)
|
|
||||||
FoursquareType string `json:"foursquare_type,omitempty"`
|
|
||||||
|
|
||||||
// Url of the thumbnail for the result
|
|
||||||
ThumbURL string `json:"thumb_url,omitempty"`
|
|
||||||
|
|
||||||
// Latitude of the venue location in degrees
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of the venue location in degrees
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the venue
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail width
|
|
||||||
ThumbWidth int `json:"thumb_width,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail height
|
|
||||||
ThumbHeight int `json:"thumb_height,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultContact represents a contact with a phone number. By
|
|
||||||
// default, this contact will be sent by the user. Alternatively, you can
|
|
||||||
// use input_message_content to send a message with the specified content
|
|
||||||
// instead of the contact.
|
|
||||||
InlineQueryResultContact struct {
|
|
||||||
// Type of the result, must be contact
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 Bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Contact's phone number
|
|
||||||
PhoneNumber string `json:"phone_number"`
|
|
||||||
|
|
||||||
// Contact's first name
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
|
|
||||||
// Contact's last name
|
|
||||||
LastName string `json:"last_name,omitempty"`
|
|
||||||
|
|
||||||
// Additional data about the contact in the form of a vCard, 0-2048 bytes
|
|
||||||
VCard string `json:"vcard,omitempty"`
|
|
||||||
|
|
||||||
// Url of the thumbnail for the result
|
|
||||||
ThumbURL string `json:"thumb_url,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the contact
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail width
|
|
||||||
ThumbWidth int `json:"thumb_width,omitempty"`
|
|
||||||
|
|
||||||
// Thumbnail height
|
|
||||||
ThumbHeight int `json:"thumb_height,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultGame represents a Game.
|
|
||||||
InlineQueryResultGame struct {
|
|
||||||
// Type of the result, must be game
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Short name of the game
|
|
||||||
GameShortName string `json:"game_short_name"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedPhoto represents a link to a photo stored on the
|
|
||||||
// Telegram servers. By default, this photo will be sent by the user with an
|
|
||||||
// optional caption. Alternatively, you can use input_message_content to
|
|
||||||
// send a message with the specified content instead of the photo.
|
|
||||||
InlineQueryResultCachedPhoto struct {
|
|
||||||
// Type of the result, must be photo
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier of the photo
|
|
||||||
PhotoFileID string `json:"photo_file_id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the photo to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the photo
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedGif represents a link to an animated GIF file
|
|
||||||
// stored on the Telegram servers. By default, this animated GIF file will
|
|
||||||
// be sent by the user with an optional caption. Alternatively, you can use
|
|
||||||
// input_message_content to send a message with specified content instead of
|
|
||||||
// the animation.
|
|
||||||
InlineQueryResultCachedGif struct {
|
|
||||||
// Type of the result, must be gif
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier for the GIF file
|
|
||||||
GifFileID string `json:"gif_file_id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the GIF file to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the GIF animation
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedMpeg4Gif represents a link to a video animation
|
|
||||||
// (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By
|
|
||||||
// default, this animated MPEG-4 file will be sent by the user with an
|
|
||||||
// optional caption. Alternatively, you can use input_message_content to
|
|
||||||
// send a message with the specified content instead of the animation.
|
|
||||||
InlineQueryResultCachedMpeg4Gif struct {
|
|
||||||
// Type of the result, must be mpeg4_gif
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier for the MP4 file
|
|
||||||
Mpeg4FileID string `json:"mpeg4_file_id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the MPEG-4 file to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the video animation
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedSticker represents a link to a sticker stored on
|
|
||||||
// the Telegram servers. By default, this sticker will be sent by the user.
|
|
||||||
// Alternatively, you can use input_message_content to send a message with
|
|
||||||
// the specified content instead of the sticker.
|
|
||||||
InlineQueryResultCachedSticker struct {
|
|
||||||
// Type of the result, must be sticker
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier of the sticker
|
|
||||||
StickerFileID string `json:"sticker_file_id"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the sticker
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedDocument represents a link to a file stored on the
|
|
||||||
// Telegram servers. By default, this file will be sent by the user with an
|
|
||||||
// optional caption. Alternatively, you can use input_message_content to
|
|
||||||
// send a message with the specified content instead of the file.
|
|
||||||
InlineQueryResultCachedDocument struct {
|
|
||||||
// Type of the result, must be document
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// A valid file identifier for the file
|
|
||||||
DocumentFileID string `json:"document_file_id"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the document to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the file
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedVideo represents a link to a video file stored on
|
|
||||||
// the Telegram servers. By default, this video file will be sent by the
|
|
||||||
// user with an optional caption. Alternatively, you can use
|
|
||||||
// input_message_content to send a message with the specified content
|
|
||||||
// instead of the video.
|
|
||||||
InlineQueryResultCachedVideo struct {
|
|
||||||
// Type of the result, must be video
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier for the video file
|
|
||||||
VideoFileID string `json:"video_file_id"`
|
|
||||||
|
|
||||||
// Title for the result
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Short description of the result
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
|
|
||||||
// Caption of the video to be sent, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the video
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedVoice represents a link to a voice message stored
|
|
||||||
// on the Telegram servers. By default, this voice message will be sent by
|
|
||||||
// the user. Alternatively, you can use input_message_content to send a
|
|
||||||
// message with the specified content instead of the voice message.
|
|
||||||
InlineQueryResultCachedVoice struct {
|
|
||||||
// Type of the result, must be voice
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier for the voice message
|
|
||||||
VoiceFileID string `json:"voice_file_id"`
|
|
||||||
|
|
||||||
// Voice message title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Caption, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the voice message
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InlineQueryResultCachedAudio represents a link to an mp3 audio file
|
|
||||||
// stored on the Telegram servers. By default, this audio file will be sent
|
|
||||||
// by the user. Alternatively, you can use input_message_content to send a
|
|
||||||
// message with the specified content instead of the audio.
|
|
||||||
InlineQueryResultCachedAudio struct {
|
|
||||||
// Type of the result, must be audio
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Unique identifier for this result, 1-64 bytes
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// A valid file identifier for the audio file
|
|
||||||
AudioFileID string `json:"audio_file_id"`
|
|
||||||
|
|
||||||
// Caption, 0-200 characters
|
|
||||||
Caption string `json:"caption,omitempty"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in the media caption.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Inline keyboard attached to the message
|
|
||||||
ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
|
|
||||||
|
|
||||||
// Content of the message to be sent instead of the audio
|
|
||||||
InputMessageContent interface{} `json:"input_message_content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputMessageContent represents the content of a message to be sent as a result
|
|
||||||
// of an inline query.
|
|
||||||
InputMessageContent interface {
|
|
||||||
IsInputMessageContent() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputTextMessageContent represents the content of a text message to be
|
|
||||||
// sent as the result of an inline query.
|
|
||||||
InputTextMessageContent struct {
|
|
||||||
// Text of the message to be sent, 1-4096 characters
|
|
||||||
MessageText string `json:"message_text"`
|
|
||||||
|
|
||||||
// Send Markdown or HTML, if you want Telegram apps to show bold, italic,
|
|
||||||
// fixed-width text or inline URLs in your bot's message.
|
|
||||||
ParseMode string `json:"parse_mode,omitempty"`
|
|
||||||
|
|
||||||
// Disables link previews for links in the sent message
|
|
||||||
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputLocationMessageContent represents the content of a location message
|
|
||||||
// to be sent as the result of an inline query.
|
|
||||||
InputLocationMessageContent struct {
|
|
||||||
// Latitude of the location in degrees
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of the location in degrees
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputVenueMessageContent represents the content of a venue message to be
|
|
||||||
// sent as the result of an inline query.
|
|
||||||
InputVenueMessageContent struct {
|
|
||||||
// Latitude of the venue in degrees
|
|
||||||
Latitude float32 `json:"latitude"`
|
|
||||||
|
|
||||||
// Longitude of the venue in degrees
|
|
||||||
Longitude float32 `json:"longitude"`
|
|
||||||
|
|
||||||
// Name of the venue
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Address of the venue
|
|
||||||
Address string `json:"address"`
|
|
||||||
|
|
||||||
// Foursquare identifier of the venue, if known
|
|
||||||
FoursquareID string `json:"foursquare_id,omitempty"`
|
|
||||||
|
|
||||||
// Foursquare type of the venue, if known. (For example,
|
|
||||||
// "arts_entertainment/default", "arts_entertainment/aquarium" or
|
|
||||||
// "food/icecream".)
|
|
||||||
FoursquareType string `json:"foursquare_type,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputContactMessageContent represents the content of a contact message to
|
|
||||||
// be sent as the result of an inline query.
|
|
||||||
InputContactMessageContent struct {
|
|
||||||
// Contact's phone number
|
|
||||||
PhoneNumber string `json:"phone_number"`
|
|
||||||
|
|
||||||
// Contact's first name
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
|
|
||||||
// Contact's last name
|
|
||||||
LastName string `json:"last_name,omitempty"`
|
|
||||||
|
|
||||||
// Additional data about the contact in the form of a vCard, 0-2048 bytes
|
|
||||||
VCard string `json:"vcard,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChosenInlineResult represents a result of an inline query that was chosen
|
|
||||||
// by the user and sent to their chat partner.
|
|
||||||
ChosenInlineResult struct {
|
|
||||||
// The unique identifier for the result that was chosen
|
|
||||||
ResultID string `json:"result_id"`
|
|
||||||
|
|
||||||
// Identifier of the sent inline message. Available only if there is an
|
|
||||||
// inline keyboard attached to the message. Will be also received in
|
|
||||||
// callback queries and can be used to edit the message.
|
|
||||||
InlineMessageID string `json:"inline_message_id,omitempty"`
|
|
||||||
|
|
||||||
// The query that was used to obtain the result
|
|
||||||
Query string `json:"query"`
|
|
||||||
|
|
||||||
// The user that chose the result
|
|
||||||
From *User `json:"from"`
|
|
||||||
|
|
||||||
// Sender location, only for bots that require user location
|
|
||||||
Location *Location `json:"location,omitempty"`
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,591 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
type (
|
|
||||||
// AuthParameters represent a Telegram Passport auth parameters for SDK.
|
|
||||||
AuthParameters struct {
|
|
||||||
// Unique identifier for the bot. You can get it from bot token.
|
|
||||||
// For example, for the bot token
|
|
||||||
// 1234567:4TT8bAc8GHUspu3ERYn-KGcvsvGB9u_n4ddy, the bot id is
|
|
||||||
// 1234567.
|
|
||||||
BotID int `json:"bot_id"`
|
|
||||||
|
|
||||||
// A JSON-serialized object describing the data you want to
|
|
||||||
// request
|
|
||||||
Scope PassportScope `json:"scope"`
|
|
||||||
|
|
||||||
// Public key of the bot
|
|
||||||
PublicKey string `json:"public_key"`
|
|
||||||
|
|
||||||
// Bot-specified nonce.
|
|
||||||
//
|
|
||||||
// Important: For security purposes it should be a
|
|
||||||
// cryptographically secure unique identifier of the request. In
|
|
||||||
// particular, it should be long enough and it should be
|
|
||||||
// generated using a cryptographically secure pseudorandom number
|
|
||||||
// generator. You should never accept credentials with the same
|
|
||||||
// nonce twice.
|
|
||||||
Nonce string `json:"nonce"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportScope represents the data to be requested.
|
|
||||||
PassportScope struct {
|
|
||||||
// List of requested elements, each type may be used only once
|
|
||||||
// in the entire array of PassportScopeElement objects
|
|
||||||
Data []PassportScopeElement `json:"data"`
|
|
||||||
|
|
||||||
// Scope version, must be 1
|
|
||||||
V int `json:"v"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportScopeElement represents a requested element.
|
|
||||||
PassportScopeElement interface {
|
|
||||||
PassportScopeElementTranslation() bool
|
|
||||||
PassportScopeElementSelfie() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
//PassportScopeElementOneOfSeveral represents several elements one of which must be provided.
|
|
||||||
PassportScopeElementOneOfSeveral struct {
|
|
||||||
// List of elements one of which must be provided;
|
|
||||||
OneOf []PassportScopeElementOne `json:"one_of"`
|
|
||||||
|
|
||||||
// Use this parameter if you want to request a selfie with the
|
|
||||||
// document from this list that the user chooses to upload.
|
|
||||||
Selfie bool `json:"selfie,omitempty"`
|
|
||||||
|
|
||||||
// Use this parameter if you want to request a translation of
|
|
||||||
// the document from this list that the user chooses to upload.
|
|
||||||
// Note: We suggest to only request translations after you have
|
|
||||||
// received a valid document that requires one.
|
|
||||||
Translation bool `json:"translation,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportScopeElementOne represents one particular element that must
|
|
||||||
// be provided. If no options are needed, String can be used instead of
|
|
||||||
// this object to specify the type of the element.
|
|
||||||
PassportScopeElementOne struct {
|
|
||||||
// Element type.
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Use this parameter if you want to request a selfie with the
|
|
||||||
// document as well.
|
|
||||||
Selfie bool `json:"selfie,omitempty"`
|
|
||||||
|
|
||||||
// Use this parameter if you want to request a translation of
|
|
||||||
// the document as well.
|
|
||||||
Translation bool `json:"translation,omitempty"`
|
|
||||||
|
|
||||||
// Use this parameter to request the first, last and middle name
|
|
||||||
// of the user in the language of the user's country of residence.
|
|
||||||
NativeNames bool `json:"native_names,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
Passport struct {
|
|
||||||
// Personal Details
|
|
||||||
PersonalDetails struct {
|
|
||||||
Data *PersonalDetails `json:"data"`
|
|
||||||
} `json:"personal_details"`
|
|
||||||
|
|
||||||
// Passport
|
|
||||||
Passport struct {
|
|
||||||
Data *IdDocumentData `json:"data"`
|
|
||||||
FrontSide *PassportFile `json:"front_side"`
|
|
||||||
Selfie *PassportFile `json:"selfie,omitempty"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"passport"`
|
|
||||||
|
|
||||||
// Internal Passport
|
|
||||||
InternalPassport struct {
|
|
||||||
Data *IdDocumentData `json:"data"`
|
|
||||||
FrontSide *PassportFile `json:"front_side"`
|
|
||||||
Selfie *PassportFile `json:"selfie,omitempty"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"internal_passport"`
|
|
||||||
|
|
||||||
// Driver License
|
|
||||||
DriverLicense struct {
|
|
||||||
Data *IdDocumentData `json:"data"`
|
|
||||||
FrontSide *PassportFile `json:"front_side"`
|
|
||||||
ReverseSide *PassportFile `json:"reverse_side"`
|
|
||||||
Selfie *PassportFile `json:"selfie,omitempty"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"driver_license"`
|
|
||||||
|
|
||||||
// Identity Card
|
|
||||||
IdentityCard struct {
|
|
||||||
Data *IdDocumentData `json:"data"`
|
|
||||||
FrontSide *PassportFile `json:"front_side"`
|
|
||||||
ReverseSide *PassportFile `json:"reverse_side"`
|
|
||||||
Selfie *PassportFile `json:"selfie,omitempty"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"identity_card"`
|
|
||||||
|
|
||||||
// Address
|
|
||||||
Address struct {
|
|
||||||
Data *ResidentialAddress `json:"data"`
|
|
||||||
} `json:"address"`
|
|
||||||
|
|
||||||
// Utility Bill
|
|
||||||
UtilityBill struct {
|
|
||||||
Files []PassportFile `json:"files"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"utility_bill"`
|
|
||||||
|
|
||||||
// Bank Statement
|
|
||||||
BankStatement struct {
|
|
||||||
Files []PassportFile `json:"files"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"bank_statement"`
|
|
||||||
|
|
||||||
// Rental Agreement
|
|
||||||
RentalAgreement struct {
|
|
||||||
Files []PassportFile `json:"files"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"rental_agreement"`
|
|
||||||
|
|
||||||
// Registration Page in the Internal Passport
|
|
||||||
PassportRegistration struct {
|
|
||||||
Files []PassportFile `json:"files"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"passport_registration"`
|
|
||||||
|
|
||||||
// Temporary Registration
|
|
||||||
TemporaryRegistration struct {
|
|
||||||
Files []PassportFile `json:"files"`
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
} `json:"temporary_registration"`
|
|
||||||
|
|
||||||
// Phone number
|
|
||||||
PhoneNumber string `json:"phone_number"`
|
|
||||||
|
|
||||||
// Email
|
|
||||||
Email string `json:"email"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PersonalDetails represents personal details.
|
|
||||||
PersonalDetails struct {
|
|
||||||
// First Name
|
|
||||||
FirstName string `json:"first_name"`
|
|
||||||
|
|
||||||
// Last Name
|
|
||||||
LastName string `json:"last_name"`
|
|
||||||
|
|
||||||
// Middle Name
|
|
||||||
MiddleName string `json:"middle_name,omitempty"`
|
|
||||||
|
|
||||||
// Date of birth in DD.MM.YYYY format
|
|
||||||
BirthDate string `json:"birth_date"`
|
|
||||||
|
|
||||||
// Gender, male or female
|
|
||||||
Gender string `json:"gender"`
|
|
||||||
|
|
||||||
// Citizenship (ISO 3166-1 alpha-2 country code)
|
|
||||||
CountryCode string `json:"country_code"`
|
|
||||||
|
|
||||||
// Country of residence (ISO 3166-1 alpha-2 country code)
|
|
||||||
ResidenceCountryCode string `json:"residence_country_code"`
|
|
||||||
|
|
||||||
// First Name in the language of the user's country of residence
|
|
||||||
FirstNameNative string `json:"first_name_native"`
|
|
||||||
|
|
||||||
// Last Name in the language of the user's country of residence
|
|
||||||
LastNameNative string `json:"last_name_native"`
|
|
||||||
|
|
||||||
// Middle Name in the language of the user's country of residence
|
|
||||||
MiddleNameNative string `json:"middle_name_native,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResidentialAddress represents a residential address.
|
|
||||||
ResidentialAddress struct {
|
|
||||||
// First line for the address
|
|
||||||
StreetLine1 string `json:"street_line1"`
|
|
||||||
|
|
||||||
// Second line for the address
|
|
||||||
StreetLine2 string `json:"street_line2,omitempty"`
|
|
||||||
|
|
||||||
// City
|
|
||||||
City string `json:"city"`
|
|
||||||
|
|
||||||
// State
|
|
||||||
State string `json:"state,omitempty"`
|
|
||||||
|
|
||||||
// ISO 3166-1 alpha-2 country code
|
|
||||||
CountryCode string `json:"country_code"`
|
|
||||||
|
|
||||||
// Address post code
|
|
||||||
PostCode string `json:"post_code"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// IdDocumentData represents the data of an identity document.
|
|
||||||
IdDocumentData struct {
|
|
||||||
// Document number
|
|
||||||
DocumentNo string `json:"document_no"`
|
|
||||||
|
|
||||||
// Date of expiry, in DD.MM.YYYY format
|
|
||||||
ExpiryDate string `json:"expiry_date,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
|
|
||||||
// File size
|
|
||||||
FileSize int `json:"file_size"`
|
|
||||||
|
|
||||||
// Unix time when the file was uploaded
|
|
||||||
FileDate int64 `json:"file_date"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Credentials is a JSON-serialized object.
|
|
||||||
Credentials struct {
|
|
||||||
// Credentials for encrypted data
|
|
||||||
SecureData *SecureData `json:"secure_data"`
|
|
||||||
|
|
||||||
// Bot-specified nonce
|
|
||||||
Nonce string `json:"nonce"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecureData represents the credentials required to decrypt encrypted
|
|
||||||
// data. All fields are optional and depend on fields that were requested.
|
|
||||||
SecureData struct {
|
|
||||||
// Credentials for encrypted personal details
|
|
||||||
PersonalDetails *SecureValue `json:"personal_details,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted passport
|
|
||||||
Passport *SecureValue `json:"passport,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted internal passport
|
|
||||||
InternalPassport *SecureValue `json:"internal_passport,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted driver license
|
|
||||||
DriverLicense *SecureValue `json:"driver_license,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted ID card
|
|
||||||
IdentityCard *SecureValue `json:"identity_card,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted residential address
|
|
||||||
Address *SecureValue `json:"address,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted utility bill
|
|
||||||
UtilityBill *SecureValue `json:"utility_bill,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted bank statement
|
|
||||||
BankStatement *SecureValue `json:"bank_statement,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted rental agreement
|
|
||||||
RentalAgreement *SecureValue `json:"rental_agreement,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted registration from internal passport
|
|
||||||
PassportRegistration *SecureValue `json:"passport_registration,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted temporary registration
|
|
||||||
TemporaryRegistration *SecureValue `json:"temporary_registration,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecureValue represents the credentials required to decrypt encrypted
|
|
||||||
// values. All fields are optional and depend on the type of fields that
|
|
||||||
// were requested.
|
|
||||||
SecureValue struct {
|
|
||||||
// Credentials for encrypted Telegram Passport data.
|
|
||||||
Data *DataCredentials `json:"data,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for an encrypted document's front side.
|
|
||||||
FrontSide *FileCredentials `json:"front_side,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for an encrypted document's reverse side.
|
|
||||||
ReverseSide *FileCredentials `json:"reverse_side,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for an encrypted selfie of the user with a document.
|
|
||||||
Selfie *FileCredentials `json:"selfie,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for an encrypted translation of the document.
|
|
||||||
Translation []FileCredentials `json:"translation,omitempty"`
|
|
||||||
|
|
||||||
// Credentials for encrypted files.
|
|
||||||
Files []FileCredentials `json:"files,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DataCredentials can be used to decrypt encrypted data from the data
|
|
||||||
// field in EncryptedPassportElement.
|
|
||||||
DataCredentials struct {
|
|
||||||
// Checksum of encrypted data
|
|
||||||
DataHash string `json:"data_hash"`
|
|
||||||
|
|
||||||
// Secret of encrypted data
|
|
||||||
Secret string `json:"secret"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileCredentials can be used to decrypt encrypted files from the
|
|
||||||
// front_side, reverse_side, selfie, files and translation fields in
|
|
||||||
// EncryptedPassportElement.
|
|
||||||
FileCredentials struct {
|
|
||||||
// Checksum of encrypted file
|
|
||||||
FileHash string `json:"file_hash"`
|
|
||||||
|
|
||||||
// Secret of encrypted file
|
|
||||||
Secret string `json:"secret"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
|
|
||||||
// Array of encrypted files with translated versions of documents
|
|
||||||
// provided by the user. Available if requested for “passport”,
|
|
||||||
// “driver_license”, “identity_card”, “internal_passport”,
|
|
||||||
// “utility_bill”, “bank_statement”, “rental_agreement”,
|
|
||||||
// “passport_registration” and “temporary_registration” types.
|
|
||||||
// Files can be decrypted and verified using the accompanying
|
|
||||||
// EncryptedCredentials.
|
|
||||||
Translation []PassportFile `json:"translation,omitempty"`
|
|
||||||
|
|
||||||
// Base64-encoded element hash for using in PassportElementErrorUnspecified
|
|
||||||
Hash string `json:"hash"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
PassportElementErrorMessage() string
|
|
||||||
PassportElementErrorSource() string
|
|
||||||
PassportElementErrorType() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportElementErrorTranslationFile represents an issue with one of the
|
|
||||||
// files that constitute the translation of a document. The error is
|
|
||||||
// considered resolved when the file changes.
|
|
||||||
PassportElementErrorTranslationFile struct {
|
|
||||||
// Error source, must be translation_file
|
|
||||||
Source string `json:"source"`
|
|
||||||
|
|
||||||
// Type of element of the user's Telegram Passport which has the issue,
|
|
||||||
// one of “passport”, “driver_license”, “identity_card”,
|
|
||||||
// “internal_passport”, “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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportElementErrorTranslationFiles represents an issue with the translated
|
|
||||||
// version of a document. The error is considered resolved when a file with the
|
|
||||||
// document translation change.
|
|
||||||
PassportElementErrorTranslationFiles struct {
|
|
||||||
// Error source, must be translation_files
|
|
||||||
Source string `json:"source"`
|
|
||||||
|
|
||||||
// Type of element of the user's Telegram Passport which has the issue,
|
|
||||||
// one of “passport”, “driver_license”, “identity_card”,
|
|
||||||
// “internal_passport”, “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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PassportElementErrorUnspecified represents an issue in an unspecified place.
|
|
||||||
// The error is considered resolved when new data is added.
|
|
||||||
PassportElementErrorUnspecified struct {
|
|
||||||
// Error source, must be unspecified
|
|
||||||
Source string `json:"source"`
|
|
||||||
|
|
||||||
// Type of element of the user's Telegram Passport which has the issue
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Base64-encoded element hash
|
|
||||||
ElementHash string `json:"element_hash"`
|
|
||||||
|
|
||||||
// Error message
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,158 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
type (
|
|
||||||
// LabeledPrice represents a portion of the price for goods or services.
|
|
||||||
LabeledPrice struct {
|
|
||||||
// Portion label
|
|
||||||
Label string `json:"label"`
|
|
||||||
|
|
||||||
// Price of the product in the smallest units of the currency (integer,
|
|
||||||
// not float/double). For example, for a price of US$ 1.45 pass amount =
|
|
||||||
// 145. See the exp parameter in currencies.json, it shows the number of
|
|
||||||
// digits past the decimal point for each currency (2 for the majority
|
|
||||||
// of currencies).
|
|
||||||
Amount int `json:"amount"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoice contains basic information about an invoice.
|
|
||||||
Invoice struct {
|
|
||||||
// Product name
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// Product description
|
|
||||||
Description string `json:"description"`
|
|
||||||
|
|
||||||
// Unique bot deep-linking parameter that can be used to generate this
|
|
||||||
// invoice
|
|
||||||
StartParameter string `json:"start_parameter"`
|
|
||||||
|
|
||||||
// Three-letter ISO 4217 currency code
|
|
||||||
Currency string `json:"currency"`
|
|
||||||
|
|
||||||
// Total price in the smallest units of the currency (integer, not
|
|
||||||
// float/double). For example, for a price of US$ 1.45 pass amount = 145.
|
|
||||||
// See the exp parameter in currencies.json, it shows the number of
|
|
||||||
// digits past the decimal point for each currency (2 for the majority
|
|
||||||
// of currencies).
|
|
||||||
TotalAmount int `json:"total_amount"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShippingAddress represents a shipping address.
|
|
||||||
ShippingAddress struct {
|
|
||||||
// ISO 3166-1 alpha-2 country code
|
|
||||||
CountryCode string `json:"country_code"`
|
|
||||||
|
|
||||||
// State, if applicable
|
|
||||||
State string `json:"state"`
|
|
||||||
|
|
||||||
// City
|
|
||||||
City string `json:"city"`
|
|
||||||
|
|
||||||
// First line for the address
|
|
||||||
StreetLine1 string `json:"street_line1"`
|
|
||||||
|
|
||||||
// Second line for the address
|
|
||||||
StreetLine2 string `json:"street_line2"`
|
|
||||||
|
|
||||||
// Address post code
|
|
||||||
PostCode string `json:"post_code"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderInfo represents information about an order.
|
|
||||||
OrderInfo struct {
|
|
||||||
// User name
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
|
|
||||||
// User's phone number
|
|
||||||
PhoneNumber string `json:"phone_number,omitempty"`
|
|
||||||
|
|
||||||
// User email
|
|
||||||
Email string `json:"email,omitempty"`
|
|
||||||
|
|
||||||
// User shipping address
|
|
||||||
ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShippingOption represents one shipping option.
|
|
||||||
ShippingOption struct {
|
|
||||||
// Shipping option identifier
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Option title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// List of price portions
|
|
||||||
Prices []LabeledPrice `json:"prices"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SuccessfulPayment contains basic information about a successful payment.
|
|
||||||
SuccessfulPayment struct {
|
|
||||||
// Three-letter ISO 4217 currency code
|
|
||||||
Currency string `json:"currency"`
|
|
||||||
|
|
||||||
// Bot specified invoice payload
|
|
||||||
InvoicePayload string `json:"invoice_payload"`
|
|
||||||
|
|
||||||
// Identifier of the shipping option chosen by the user
|
|
||||||
ShippingOptionID string `json:"shipping_option_id,omitempty"`
|
|
||||||
|
|
||||||
// Telegram payment identifier
|
|
||||||
TelegramPaymentChargeID string `json:"telegram_payment_charge_id"`
|
|
||||||
|
|
||||||
// Provider payment identifier
|
|
||||||
ProviderPaymentChargeID string `json:"provider_payment_charge_id"`
|
|
||||||
|
|
||||||
// Total price in the smallest units of the currency (integer, not
|
|
||||||
// float/double). For example, for a price of US$ 1.45 pass amount = 145.
|
|
||||||
// See the exp parameter in currencies.json, it shows the number of
|
|
||||||
// digits past the decimal point for each currency (2 for the majority
|
|
||||||
// of currencies).
|
|
||||||
TotalAmount int `json:"total_amount"`
|
|
||||||
|
|
||||||
// Order info provided by the user
|
|
||||||
OrderInfo *OrderInfo `json:"order_info,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShippingQuery contains information about an incoming shipping query.
|
|
||||||
ShippingQuery struct {
|
|
||||||
// Unique query identifier
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Bot specified invoice payload
|
|
||||||
InvoicePayload string `json:"invoice_payload"`
|
|
||||||
|
|
||||||
// User who sent the query
|
|
||||||
From *User `json:"from"`
|
|
||||||
|
|
||||||
// User specified shipping address
|
|
||||||
ShippingAddress *ShippingAddress `json:"shipping_address"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreCheckoutQuery contains information about an incoming pre-checkout query.
|
|
||||||
PreCheckoutQuery struct {
|
|
||||||
// Unique query identifier
|
|
||||||
ID string `json:"id"`
|
|
||||||
|
|
||||||
// Three-letter ISO 4217 currency code
|
|
||||||
Currency string `json:"currency"`
|
|
||||||
|
|
||||||
// Bot specified invoice payload
|
|
||||||
InvoicePayload string `json:"invoice_payload"`
|
|
||||||
|
|
||||||
// Identifier of the shipping option chosen by the user
|
|
||||||
ShippingOptionID string `json:"shipping_option_id,omitempty"`
|
|
||||||
|
|
||||||
// User who sent the query
|
|
||||||
From *User `json:"from"`
|
|
||||||
|
|
||||||
// Total price in the smallest units of the currency (integer, not
|
|
||||||
// float/double). For example, for a price of US$ 1.45 pass amount = 145.
|
|
||||||
// See the exp parameter in currencies.json, it shows the number of
|
|
||||||
// digits past the decimal point for each currency (2 for the majority of
|
|
||||||
// currencies).
|
|
||||||
TotalAmount int `json:"total_amount"`
|
|
||||||
|
|
||||||
// Order info provided by the user
|
|
||||||
OrderInfo *OrderInfo `json:"order_info,omitempty"`
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,66 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Sticker represents a sticker.
|
|
||||||
Sticker struct {
|
|
||||||
// Unique identifier for this file
|
|
||||||
FileID string `json:"file_id"`
|
|
||||||
|
|
||||||
// Emoji associated with the sticker
|
|
||||||
Emoji string `json:"emoji,omitempty"`
|
|
||||||
|
|
||||||
// Name of the sticker set to which the sticker belongs
|
|
||||||
SetName string `json:"set_name,omitempty"`
|
|
||||||
|
|
||||||
// Sticker width
|
|
||||||
Width int `json:"width"`
|
|
||||||
|
|
||||||
// Sticker height
|
|
||||||
Height int `json:"height"`
|
|
||||||
|
|
||||||
// File size
|
|
||||||
FileSize int `json:"file_size,omitempty"`
|
|
||||||
|
|
||||||
// Sticker thumbnail in the .webp or .jpg format
|
|
||||||
Thumb *PhotoSize `json:"thumb,omitempty"`
|
|
||||||
|
|
||||||
// For mask stickers, the position where the mask should be placed
|
|
||||||
MaskPosition *MaskPosition `json:"mask_position,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StickerSet represents a sticker set.
|
|
||||||
StickerSet struct {
|
|
||||||
// Sticker set name
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Sticker set title
|
|
||||||
Title string `json:"title"`
|
|
||||||
|
|
||||||
// True, if the sticker set contains masks
|
|
||||||
ContainsMasks bool `json:"contains_masks"`
|
|
||||||
|
|
||||||
// List of all set stickers
|
|
||||||
Stickers []Sticker `json:"stickers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaskPosition describes the position on faces where a mask should be placed
|
|
||||||
// by default.
|
|
||||||
MaskPosition struct {
|
|
||||||
// The part of the face relative to which the mask should be placed. One
|
|
||||||
// of "forehead", "eyes", "mouth", or "chin".
|
|
||||||
Point string `json:"point"`
|
|
||||||
|
|
||||||
// Shift by X-axis measured in widths of the mask scaled to the face
|
|
||||||
// size, from left to right. For example, choosing -1.0 will place mask
|
|
||||||
// just to the left of the default mask position.
|
|
||||||
XShift float32 `json:"x_shift"`
|
|
||||||
|
|
||||||
// Shift by Y-axis measured in heights of the mask scaled to the face
|
|
||||||
// size, from top to bottom. For example, 1.0 will place the mask just
|
|
||||||
// below the default mask position.
|
|
||||||
YShift float32 `json:"y_shift"`
|
|
||||||
|
|
||||||
// Mask scaling coefficient. For example, 2.0 means double size.
|
|
||||||
Scale float32 `json:"scale"`
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// UnbanChatMemberParameters represents data for UnbanChatMember method.
|
// UnbanChatMemberParameters represents data for UnbanChatMember method.
|
||||||
type UnbanChatMemberParameters struct {
|
type UnbanChatMemberParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -14,20 +12,22 @@ type UnbanChatMemberParameters struct {
|
||||||
// user will not return to the group or channel automatically, but will be able
|
// user will not return to the group or channel automatically, but will be able
|
||||||
// to join via link, etc. The bot must be an administrator for this to work.
|
// to join via link, etc. The bot must be an administrator for this to work.
|
||||||
// Returns True on success.
|
// Returns True on success.
|
||||||
func (bot *Bot) UnbanChatMember(chatID int64, userID int) (ok bool, err error) {
|
func (bot *Bot) UnbanChatMember(chatID int64, userID int) (bool, error) {
|
||||||
dst, err := json.Marshal(&UnbanChatMemberParameters{
|
params := UnbanChatMemberParameters{
|
||||||
ChatID: chatID,
|
ChatID: chatID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
})
|
}
|
||||||
|
dst, err := parser.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodUnbanChatMember)
|
resp, err := bot.request(dst, MethodUnbanChatMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
var ok bool
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
}
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
package telegram
|
package telegram
|
||||||
|
|
||||||
import json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
|
|
||||||
// UnpinChatMessageParameters represents data for UnpinChatMessage method.
|
// UnpinChatMessageParameters represents data for UnpinChatMessage method.
|
||||||
type UnpinChatMessageParameters struct {
|
type UnpinChatMessageParameters struct {
|
||||||
// Unique identifier for the target chat
|
// Unique identifier for the target chat
|
||||||
|
@ -11,17 +9,18 @@ type UnpinChatMessageParameters struct {
|
||||||
// UnpinChatMessage unpin a message in a supergroup chat. The bot must be an
|
// UnpinChatMessage unpin a message in a supergroup chat. The bot must be an
|
||||||
// administrator in the chat for this to work and must have the appropriate admin
|
// administrator in the chat for this to work and must have the appropriate admin
|
||||||
// rights. Returns True on success.
|
// rights. Returns True on success.
|
||||||
func (bot *Bot) UnpinChatMessage(chatID int64) (ok bool, err error) {
|
func (bot *Bot) UnpinChatMessage(chatID int64) (bool, error) {
|
||||||
dst, err := json.Marshal(&UnpinChatMessageParameters{ChatID: chatID})
|
dst, err := parser.Marshal(&UnpinChatMessageParameters{ChatID: chatID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := bot.request(dst, MethodUnpinChatMessage)
|
resp, err := bot.request(dst, MethodUnpinChatMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(*resp.Result, &ok)
|
var ok bool
|
||||||
return
|
err = parser.Unmarshal(resp.Result, &ok)
|
||||||
|
return ok, err
|
||||||
}
|
}
|
75
upload.go
75
upload.go
|
@ -7,13 +7,20 @@ import (
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/kirillDanshin/dlog"
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
http "github.com/valyala/fasthttp"
|
http "github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UploadStickerFileParameters struct {
|
||||||
|
// User identifier of sticker file owner
|
||||||
|
UserID int `json:"user_id"`
|
||||||
|
|
||||||
|
// Png image with the sticker, must be up to 512 kilobytes in size,
|
||||||
|
// dimensions must not exceed 512px, and either width or height
|
||||||
|
// must be exactly 512px.
|
||||||
|
PNGSticker interface{} `json:"png_sticker"`
|
||||||
|
}
|
||||||
|
|
||||||
// ErrBadFileType describes error of the unsupported file data type for uploading
|
// ErrBadFileType describes error of the unsupported file data type for uploading
|
||||||
var ErrBadFileType = errors.New("bad file type")
|
var ErrBadFileType = errors.New("bad file type")
|
||||||
|
|
||||||
|
@ -54,7 +61,7 @@ voice notes will be sent as files.
|
||||||
|
|
||||||
* Other configurations may work but we can't guarantee that they will.
|
* Other configurations may work but we can't guarantee that they will.
|
||||||
*/
|
*/
|
||||||
func (b *Bot) Upload(method, key, name string, file InputFile, args *http.Args) (response *Response, err error) {
|
func (b *Bot) Upload(method, key, name string, file InputFile, args *http.Args) (*Response, error) {
|
||||||
buffer := bytes.NewBuffer(nil)
|
buffer := bytes.NewBuffer(nil)
|
||||||
multi := multipart.NewWriter(buffer)
|
multi := multipart.NewWriter(buffer)
|
||||||
|
|
||||||
|
@ -67,12 +74,12 @@ func (b *Bot) Upload(method, key, name string, file InputFile, args *http.Args)
|
||||||
_ = multi.WriteField(string(key), string(value))
|
_ = multi.WriteField(string(key), string(value))
|
||||||
})
|
})
|
||||||
|
|
||||||
if err = createFileField(multi, file, key, name); err != nil {
|
if err := createFileField(multi, file, key, name); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = multi.Close(); err != nil {
|
if err := multi.Close(); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := http.AcquireRequest()
|
req := http.AcquireRequest()
|
||||||
|
@ -81,49 +88,41 @@ func (b *Bot) Upload(method, key, name string, file InputFile, args *http.Args)
|
||||||
req.Header.SetContentType(multi.FormDataContentType())
|
req.Header.SetContentType(multi.FormDataContentType())
|
||||||
req.Header.SetMethod("POST")
|
req.Header.SetMethod("POST")
|
||||||
req.Header.SetRequestURI(requestURI.String())
|
req.Header.SetRequestURI(requestURI.String())
|
||||||
req.Header.SetUserAgent(path.Join("telegram", strconv.FormatInt(Version, 10)))
|
req.Header.SetUserAgent(path.Join("telegram", Version))
|
||||||
req.Header.SetHostBytes(requestURI.Host())
|
req.Header.SetHostBytes(requestURI.Host())
|
||||||
|
|
||||||
log.Ln("Request:")
|
|
||||||
log.D(req)
|
|
||||||
|
|
||||||
resp := http.AcquireResponse()
|
resp := http.AcquireResponse()
|
||||||
defer http.ReleaseResponse(resp)
|
defer http.ReleaseResponse(resp)
|
||||||
|
|
||||||
err = http.Do(req, resp)
|
if err := http.Do(req, resp); err != nil {
|
||||||
log.Ln("Resp:")
|
return nil, err
|
||||||
log.D(resp)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = new(Response)
|
var response Response
|
||||||
if err = json.Unmarshal(resp.Body(), response); err != nil {
|
if err := parser.Unmarshal(resp.Body(), &response); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !response.Ok {
|
if !response.Ok {
|
||||||
err = errors.New(response.Description)
|
return nil, errors.New(response.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return &response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFileField(w *multipart.Writer, file interface{}, key, val string) (err error) {
|
func createFileField(w *multipart.Writer, file interface{}, key, val string) (err error) {
|
||||||
switch src := file.(type) {
|
switch src := file.(type) {
|
||||||
case string: // Send FileID of file on disk path
|
case string: // Send FileID of file on disk path
|
||||||
err = createFileFieldString(w, key, src)
|
return createFileFieldString(w, key, src)
|
||||||
case *http.URI: // Send by URL
|
case *http.URI: // Send by URL
|
||||||
err = w.WriteField(key, src.String())
|
return w.WriteField(key, src.String())
|
||||||
case []byte: // Upload new
|
case []byte: // Upload new
|
||||||
err = createFileFieldRaw(w, key, val, bytes.NewReader(src))
|
return createFileFieldRaw(w, key, val, bytes.NewReader(src))
|
||||||
case io.Reader: // Upload new
|
case io.Reader: // Upload new
|
||||||
err = createFileFieldRaw(w, key, val, src)
|
return createFileFieldRaw(w, key, val, src)
|
||||||
default:
|
default:
|
||||||
err = ErrBadFileType
|
return ErrBadFileType
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFileFieldString(w *multipart.Writer, key, src string) (err error) {
|
func createFileFieldString(w *multipart.Writer, key, src string) (err error) {
|
||||||
|
@ -167,3 +166,21 @@ func createFileFieldRaw(w *multipart.Writer, key, value string, src io.Reader) e
|
||||||
_, err = io.Copy(field, src)
|
_, err = io.Copy(field, src)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UploadStickerFile upload a .png file with a sticker for later use in
|
||||||
|
// createNewStickerSet and addStickerToSet methods (can be used multiple times).
|
||||||
|
// Returns the uploaded File on success.
|
||||||
|
func (b *Bot) UploadStickerFile(userID int, pngSticker interface{}) (*File, error) {
|
||||||
|
args := http.AcquireArgs()
|
||||||
|
defer http.ReleaseArgs(args)
|
||||||
|
args.SetUint("user_id", userID)
|
||||||
|
|
||||||
|
resp, err := b.Upload(MethodUploadStickerFile, TypeSticker, "sticker", pngSticker, args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var f File
|
||||||
|
err = parser.Unmarshal(resp.Result, &f)
|
||||||
|
return &f, err
|
||||||
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
func (a *Animation) HasThumb() bool {
|
|
||||||
return a != nil && a.Thumb != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Animation) File() *File {
|
|
||||||
if a == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &File{
|
|
||||||
FileID: a.FileID,
|
|
||||||
FileSize: a.FileSize,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
func (a *Audio) FullName(sep string) (name string) {
|
|
||||||
if !a.HasTitle() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.HasPerformer() {
|
|
||||||
name += a.Performer + sep
|
|
||||||
}
|
|
||||||
|
|
||||||
name += a.Title
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Audio) HasPerformer() bool {
|
|
||||||
return a != nil && a.Performer != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Audio) HasTitle() bool {
|
|
||||||
return a != nil && a.Title != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Audio) HasThumb() bool {
|
|
||||||
return a != nil && a.Thumb != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Audio) File() *File {
|
|
||||||
if a == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &File{
|
|
||||||
FileID: a.FileID,
|
|
||||||
FileSize: a.FileSize,
|
|
||||||
}
|
|
||||||
}
|
|
205
utils_bot.go
205
utils_bot.go
|
@ -1,205 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Bot represents a bot user with access token getted from @BotFather and
|
|
||||||
// fasthttp.Client for requests.
|
|
||||||
type Bot struct {
|
|
||||||
*User
|
|
||||||
AccessToken string
|
|
||||||
Client *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetClient allow set custom fasthttp.Client (for proxy traffic, for example).
|
|
||||||
func (b *Bot) SetClient(newClient *http.Client) {
|
|
||||||
if b == nil {
|
|
||||||
b = new(Bot)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.Client = newClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new default Bot structure based on the input access token.
|
|
||||||
func New(accessToken string) (*Bot, error) {
|
|
||||||
var err error
|
|
||||||
b := new(Bot)
|
|
||||||
b.SetClient(defaultClient)
|
|
||||||
b.AccessToken = accessToken
|
|
||||||
|
|
||||||
b.User, err = b.GetMe()
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMessageFromMe checks that the input message is a message from the current
|
|
||||||
// bot.
|
|
||||||
func (b *Bot) IsMessageFromMe(m *Message) bool {
|
|
||||||
return b != nil && b.User != nil &&
|
|
||||||
m != nil && m.From != nil && m.From.ID == b.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsForwardFromMe checks that the input message is a forwarded message from the
|
|
||||||
// current bot.
|
|
||||||
func (b *Bot) IsForwardFromMe(m *Message) bool {
|
|
||||||
return b != nil && b.User != nil &&
|
|
||||||
m.IsForward() && m.ForwardFrom.ID == b.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsReplyToMe checks that the input message is a reply to the current bot.
|
|
||||||
func (b *Bot) IsReplyToMe(m *Message) bool {
|
|
||||||
return m.Chat.IsPrivate() ||
|
|
||||||
(m.IsReply() && b.IsMessageFromMe(m.ReplyToMessage))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCommandToMe checks that the input message is a command for the current bot.
|
|
||||||
func (b *Bot) IsCommandToMe(m *Message) bool {
|
|
||||||
if !m.IsCommand() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Chat.IsPrivate() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := strings.Split(m.RawCommand(), "@")
|
|
||||||
if len(parts) <= 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.EqualFold(parts[1], b.User.Username)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMessageMentionsMe checks that the input message mentions the current bot.
|
|
||||||
func (b *Bot) IsMessageMentionsMe(m *Message) bool {
|
|
||||||
if b == nil || b.User == nil ||
|
|
||||||
m == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.IsCommandToMe(m) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var entities []MessageEntity
|
|
||||||
switch {
|
|
||||||
case m.HasMentions():
|
|
||||||
entities = m.Entities
|
|
||||||
case m.HasCaptionMentions():
|
|
||||||
entities = m.CaptionEntities
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entity := range entities {
|
|
||||||
if entity.IsMention() && entity.User.ID == b.ID {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsForwardMentionsMe checks that the input forwarded message mentions the
|
|
||||||
// current bot.
|
|
||||||
func (b *Bot) IsForwardMentionsMe(m *Message) bool {
|
|
||||||
return m.IsForward() && b.IsMessageMentionsMe(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsReplyMentionsMe checks that the input message mentions the current bot.
|
|
||||||
func (b *Bot) IsReplyMentionsMe(m *Message) bool {
|
|
||||||
return m.IsReply() && b.IsMessageMentionsMe(m.ReplyToMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMessageToMe checks that the input message is addressed to the current bot.
|
|
||||||
func (b *Bot) IsMessageToMe(m *Message) bool {
|
|
||||||
if m == nil || m.Chat == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Chat.IsPrivate() ||
|
|
||||||
b.IsCommandToMe(m) ||
|
|
||||||
b.IsReplyToMe(m) ||
|
|
||||||
b.IsMessageMentionsMe(m) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFileURL creates a url.URL to file with path getted from GetFile method.
|
|
||||||
func (b *Bot) NewFileURL(filePath string) *http.URI {
|
|
||||||
if b == nil || b.AccessToken == "" ||
|
|
||||||
filePath == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
result := http.AcquireURI()
|
|
||||||
result.SetScheme("https")
|
|
||||||
result.SetHost("api.telegram.org")
|
|
||||||
result.SetPath(path.Join("file", "bot"+b.AccessToken, filePath))
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRedirectURL creates new url.URL for redirecting from one chat to another.
|
|
||||||
func (b *Bot) NewRedirectURL(param string, group bool) *http.URI {
|
|
||||||
if b == nil || b.User == nil || b.User.Username == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
link := http.AcquireURI()
|
|
||||||
link.SetScheme("https")
|
|
||||||
link.SetHost("t.me")
|
|
||||||
link.SetPath(b.User.Username)
|
|
||||||
|
|
||||||
q := link.QueryArgs()
|
|
||||||
key := "start"
|
|
||||||
if group {
|
|
||||||
key += "group"
|
|
||||||
}
|
|
||||||
q.Set(key, param)
|
|
||||||
|
|
||||||
link.SetQueryStringBytes(q.QueryString())
|
|
||||||
|
|
||||||
return link
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Bot) DecryptFile(pf *PassportFile, fc *FileCredentials) (data []byte, err error) {
|
|
||||||
secret, err := decodeField(fc.Secret)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := decodeField(fc.FileHash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key, iv := decryptSecretHash(secret, hash)
|
|
||||||
file, err := b.GetFile(pf.FileID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, data, err = b.Client.Get(nil, b.NewFileURL(file.FilePath).String())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err = decryptData(key, iv, data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !match(hash, data) {
|
|
||||||
err = ErrNotEqual
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := int(data[0])
|
|
||||||
data = data[offset:]
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
// IsPrivate checks that the current chat is a private chat with single user.
|
|
||||||
func (c *Chat) IsPrivate() bool {
|
|
||||||
return c != nil && strings.EqualFold(c.Type, ChatPrivate)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsGroup checks that the current chat is a group.
|
|
||||||
func (c *Chat) IsGroup() bool {
|
|
||||||
return c != nil && strings.EqualFold(c.Type, ChatGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSuperGroup checks that the current chat is a supergroup.
|
|
||||||
func (c *Chat) IsSuperGroup() bool {
|
|
||||||
return c != nil && strings.EqualFold(c.Type, ChatSuperGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsChannel checks that the current chat is a channel.
|
|
||||||
func (c *Chat) IsChannel() bool {
|
|
||||||
return c != nil && strings.EqualFold(c.Type, ChatChannel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasPinnedMessage checks that the current chat has a pinned message.
|
|
||||||
func (c *Chat) HasPinnedMessage() bool {
|
|
||||||
return c != nil && c.PinnedMessage != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasStickerSet checks that the current chat has a sticker set.
|
|
||||||
func (c *Chat) HasStickerSet() bool {
|
|
||||||
return c != nil && c.StickerSetName != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// StickerSet return StickerSet structure if StickerSetName is available.
|
|
||||||
func (c *Chat) StickerSet(bot *Bot) *StickerSet {
|
|
||||||
if !c.HasStickerSet() || bot == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
set, err := bot.GetStickerSet(c.StickerSetName)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
// FullName returns the full name of chat or FirstName if LastName is not available.
|
|
||||||
func (c *Chat) FullName() string {
|
|
||||||
if c == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.HasLastName() {
|
|
||||||
return c.FirstName + " " + c.LastName
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.FirstName
|
|
||||||
}
|
|
||||||
|
|
||||||
// HaveLastName checks what the current user has a LastName.
|
|
||||||
func (c *Chat) HasLastName() bool {
|
|
||||||
return c != nil && c.LastName != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// HaveUsername checks what the current user has a username.
|
|
||||||
func (c *Chat) HasUsername() bool {
|
|
||||||
return c != nil && c.Username != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Chat) HasDescription() bool {
|
|
||||||
return c != nil && c.Description != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Chat) HasInviteLink() bool {
|
|
||||||
return c != nil && c.InviteLink != ""
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
func (cir *ChosenInlineResult) HasLocation() bool {
|
|
||||||
return cir != nil && cir.Location != nil
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
// FullName returns the full name of contact or FirstName if LastName is not
|
|
||||||
// available.
|
|
||||||
func (c *Contact) FullName() string {
|
|
||||||
if c == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.HasLastName() {
|
|
||||||
return c.FirstName + " " + c.LastName
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.FirstName
|
|
||||||
}
|
|
||||||
|
|
||||||
// HaveLastName checks what the current contact has a LastName.
|
|
||||||
func (c *Contact) HasLastName() bool {
|
|
||||||
return c != nil && c.LastName != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Contact) HasTelegram() bool {
|
|
||||||
return c != nil && c.UserID != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Contact) HasVCard() bool {
|
|
||||||
return c != nil && c.VCard != ""
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
var ErrNotEqual = errors.New("credentials hash and credentials data hash is not equal")
|
|
||||||
|
|
||||||
func (dc *DataCredentials) decrypt(d string) (data []byte, err error) {
|
|
||||||
secret, err := decodeField(dc.Secret)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hash, err := decodeField(dc.DataHash)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
key, iv := decryptSecretHash(secret, hash)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err = decodeField(d)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err = decryptData(key, iv, data)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !match(hash, data) {
|
|
||||||
err = ErrNotEqual
|
|
||||||
}
|
|
||||||
|
|
||||||
offset := int(data[0])
|
|
||||||
data = data[offset:]
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
func (d *Document) HasThumb() bool {
|
|
||||||
return d != nil && d.Thumb != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Document) File() *File {
|
|
||||||
return &File{
|
|
||||||
FileID: d.FileID,
|
|
||||||
FileSize: d.FileSize,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rsa"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ec *EncryptedCredentials) Decrypt(pk *rsa.PrivateKey) (*Credentials, error) {
|
|
||||||
if ec == nil || pk == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := decrypt(pk, ec.Secret, ec.Hash, ec.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var c Credentials
|
|
||||||
err = json.Unmarshal(data, &c)
|
|
||||||
return &c, err
|
|
||||||
}
|
|
|
@ -1,196 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
json "github.com/pquerna/ffjson/ffjson"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) DecryptPersonalDetails(sv *SecureValue) (*PersonalDetails, error) {
|
|
||||||
if !epe.IsPersonalDetails() || !sv.HasData() {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := sv.Data.decrypt(epe.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pd PersonalDetails
|
|
||||||
err = json.Unmarshal(body, &pd)
|
|
||||||
return &pd, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) DecryptPassport(sv *SecureValue, b *Bot) (*IdDocumentData, []byte, []byte, [][]byte, error) {
|
|
||||||
if !epe.IsPassport() || !sv.HasData() || !sv.HasFrontSide() {
|
|
||||||
return nil, nil, nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := sv.Data.decrypt(epe.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var idd IdDocumentData
|
|
||||||
if err = json.Unmarshal(body, &idd); err != nil {
|
|
||||||
return nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fs, err := b.DecryptFile(epe.FrontSide, sv.FrontSide)
|
|
||||||
if err != nil {
|
|
||||||
return &idd, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var s []byte
|
|
||||||
if sv.HasSelfie() {
|
|
||||||
if s, err = b.DecryptFile(epe.Selfie, sv.Selfie); err != nil {
|
|
||||||
return &idd, fs, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := make([][]byte, len(sv.Translation))
|
|
||||||
if sv.HasTranslation() {
|
|
||||||
for i := range t {
|
|
||||||
if t[i], err = b.DecryptFile(&epe.Translation[i], &sv.Translation[i]); err != nil {
|
|
||||||
return &idd, fs, s, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &idd, fs, s, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) DecryptInternalPassport(sv *SecureValue, b *Bot) (*IdDocumentData, []byte, []byte, [][]byte, error) {
|
|
||||||
if !epe.IsInternalPassport() || !sv.HasData() || !sv.HasFrontSide() {
|
|
||||||
return nil, nil, nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := sv.Data.decrypt(epe.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var idd IdDocumentData
|
|
||||||
if err = json.Unmarshal(body, &idd); err != nil {
|
|
||||||
return nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fs, err := b.DecryptFile(epe.FrontSide, sv.FrontSide)
|
|
||||||
if err != nil {
|
|
||||||
return &idd, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var s []byte
|
|
||||||
if sv.HasSelfie() {
|
|
||||||
if s, err = b.DecryptFile(epe.Selfie, sv.Selfie); err != nil {
|
|
||||||
return &idd, fs, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := make([][]byte, len(sv.Translation))
|
|
||||||
if sv.HasTranslation() {
|
|
||||||
for i := range t {
|
|
||||||
if t[i], err = b.DecryptFile(&epe.Translation[i], &sv.Translation[i]); err != nil {
|
|
||||||
return &idd, fs, s, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &idd, fs, s, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) DecryptDriverLicense(sv *SecureValue, b *Bot) (*IdDocumentData, []byte, []byte, []byte, [][]byte, error) {
|
|
||||||
if !epe.IsDriverLicense() || !sv.HasData() || !sv.HasFrontSide() || !sv.HasReverseSide() {
|
|
||||||
return nil, nil, nil, nil, nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := sv.Data.decrypt(epe.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var idd IdDocumentData
|
|
||||||
if err = json.Unmarshal(body, &idd); err != nil {
|
|
||||||
return nil, nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fs, err := b.DecryptFile(epe.FrontSide, sv.FrontSide)
|
|
||||||
if err != nil {
|
|
||||||
return &idd, nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rs, err := b.DecryptFile(epe.ReverseSide, sv.ReverseSide)
|
|
||||||
if err != nil {
|
|
||||||
return &idd, nil, nil, nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var s []byte
|
|
||||||
if sv.HasSelfie() {
|
|
||||||
if s, err = b.DecryptFile(epe.Selfie, sv.Selfie); err != nil {
|
|
||||||
return &idd, fs, rs, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t := make([][]byte, len(sv.Translation))
|
|
||||||
if sv.HasTranslation() {
|
|
||||||
for i := range t {
|
|
||||||
if t[i], err = b.DecryptFile(&epe.Translation[i], &sv.Translation[i]); err != nil {
|
|
||||||
return &idd, fs, rs, s, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &idd, fs, rs, s, t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsAddress() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsBankStatement() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeBankStatement)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsDriverLicense() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeDriverLicense)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsEmail() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeEmail)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsIdentityCard() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeIdentityCard)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsInternalPassport() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeInternalPassport)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsPassport() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypePassport)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsPassportRegistration() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypePassportRegistration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsPersonalDetails() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypePersonalDetails)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsPhoneNumber() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypePhoneNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsRentalAgreement() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeRentalAgreement)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsTemporaryRegistration() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeTemporaryRegistration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epe *EncryptedPassportElement) IsUtilityBill() bool {
|
|
||||||
return epe != nil && strings.EqualFold(epe.Type, TypeUtilityBill)
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
http "github.com/valyala/fasthttp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseURL selects URL from entered text of message and parse it as fasthttp.URI.
|
|
||||||
func (e *MessageEntity) ParseURL(messageText string) *http.URI {
|
|
||||||
if e == nil || !e.IsURL() || messageText == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
from := e.Offset
|
|
||||||
to := from + e.Length
|
|
||||||
text := []rune(messageText)
|
|
||||||
if len(text) < to {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
link := http.AcquireURI()
|
|
||||||
link.Update(string(text[from:to]))
|
|
||||||
|
|
||||||
return link
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsBold checks that the current entity is a bold tag.
|
|
||||||
func (e *MessageEntity) IsBold() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityBold)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsBotCommand checks that the current entity is a bot command.
|
|
||||||
func (e *MessageEntity) IsBotCommand() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityBotCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsCode checks that the current entity is a code tag.
|
|
||||||
func (e *MessageEntity) IsCode() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmail checks that the current entity is a email.
|
|
||||||
func (e *MessageEntity) IsEmail() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityEmail)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsHashtag checks that the current entity is a hashtag.
|
|
||||||
func (e *MessageEntity) IsHashtag() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityHashtag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsItalic checks that the current entity is a italic tag.
|
|
||||||
func (e *MessageEntity) IsItalic() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityItalic)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMention checks that the current entity is a username mention.
|
|
||||||
func (e *MessageEntity) IsMention() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityMention)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsPre checks that the current entity is a pre tag.
|
|
||||||
func (e *MessageEntity) IsPre() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityPre)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTextLink checks that the current entity is a text link.
|
|
||||||
func (e *MessageEntity) IsTextLink() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityTextLink)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTextMention checks that the current entity is a mention without username.
|
|
||||||
func (e *MessageEntity) IsTextMention() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityTextMention)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsURL checks that the current entity is a URL
|
|
||||||
func (e *MessageEntity) IsURL() bool {
|
|
||||||
return e != nil && strings.EqualFold(e.Type, EntityURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TextLink parse current text link entity as fasthttp.URI.
|
|
||||||
func (e *MessageEntity) TextLink() *http.URI {
|
|
||||||
if e == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
link := http.AcquireURI()
|
|
||||||
link.Update(e.URL)
|
|
||||||
|
|
||||||
return link
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package telegram
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func (idd *IdDocumentData) ExpiryTime() *time.Time {
|
|
||||||
if idd == nil || idd.ExpiryDate == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
et, err := time.Parse("02.01.2006", idd.ExpiryDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &et
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue