mirror of
https://github.com/crazy-max/diun.git
synced 2026-01-03 11:35:02 +01:00
chore(deps): bump github.com/PaulSonOfLars/gotgbot/v2
Bumps [github.com/PaulSonOfLars/gotgbot/v2](https://github.com/PaulSonOfLars/gotgbot) from 2.0.0-rc.27 to 2.0.0-rc.30. - [Release notes](https://github.com/PaulSonOfLars/gotgbot/releases) - [Commits](https://github.com/PaulSonOfLars/gotgbot/compare/v2.0.0-rc.27...v2.0.0-rc.30) --- updated-dependencies: - dependency-name: github.com/PaulSonOfLars/gotgbot/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30
|
||||
github.com/alecthomas/kong v0.9.0
|
||||
github.com/bmatcuk/doublestar/v3 v3.0.0
|
||||
github.com/containerd/platforms v0.2.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -13,8 +13,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27 h1:rOlGzmYC3jPVPLVLWKMiiYuePQ6MV8Cyw5qJYBoMnkY=
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU=
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30 h1:kPFkEzqg3+5gu077Zrg+24d0rO0Iwdx/ZUUHFFprfsc=
|
||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU=
|
||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
|
||||
35
vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go
generated
vendored
35
vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go
generated
vendored
@@ -1,15 +1,23 @@
|
||||
package gotgbot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:generate go run ./scripts/generate
|
||||
|
||||
var (
|
||||
ErrNilBotClient = errors.New("nil BotClient")
|
||||
ErrInvalidTokenFormat = errors.New("invalid token format")
|
||||
)
|
||||
|
||||
// Bot is the default Bot struct used to send and receive messages to the telegram API.
|
||||
type Bot struct {
|
||||
// Token stores the bot's secret token obtained from t.me/BotFather, and used to interact with telegram's API.
|
||||
@@ -75,6 +83,24 @@ func NewBot(token string, opts *BotOpts) (*Bot, error) {
|
||||
return nil, fmt.Errorf("failed to check bot token: %w", err)
|
||||
}
|
||||
b.User = *botUser
|
||||
} else {
|
||||
// If token checks are disabled, we populate the bot's ID from the token.
|
||||
split := strings.Split(token, ":")
|
||||
if len(split) != 2 {
|
||||
return nil, fmt.Errorf("%w: expected '123:abcd', got %s", ErrInvalidTokenFormat, token)
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(split[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse bot ID from token: %w", err)
|
||||
}
|
||||
b.User = User{
|
||||
Id: id,
|
||||
IsBot: true,
|
||||
// We mark these fields as missing so we can know why they're not available
|
||||
FirstName: "<missing>",
|
||||
Username: "<missing>",
|
||||
}
|
||||
}
|
||||
|
||||
return &b, nil
|
||||
@@ -88,15 +114,14 @@ func (bot *Bot) UseMiddleware(mw func(client BotClient) BotClient) *Bot {
|
||||
return bot
|
||||
}
|
||||
|
||||
var ErrNilBotClient = errors.New("nil BotClient")
|
||||
func (bot *Bot) Request(method string, params map[string]string, data map[string]FileReader, opts *RequestOpts) (json.RawMessage, error) {
|
||||
return bot.RequestWithContext(context.Background(), method, params, data, opts)
|
||||
}
|
||||
|
||||
func (bot *Bot) Request(method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) {
|
||||
func (bot *Bot) RequestWithContext(ctx context.Context, method string, params map[string]string, data map[string]FileReader, opts *RequestOpts) (json.RawMessage, error) {
|
||||
if bot.BotClient == nil {
|
||||
return nil, ErrNilBotClient
|
||||
}
|
||||
|
||||
ctx, cancel := bot.BotClient.TimeoutContext(opts)
|
||||
defer cancel()
|
||||
|
||||
return bot.BotClient.RequestWithContext(ctx, bot.Token, method, params, data, opts)
|
||||
}
|
||||
|
||||
94
vendor/github.com/PaulSonOfLars/gotgbot/v2/file.go
generated
vendored
Normal file
94
vendor/github.com/PaulSonOfLars/gotgbot/v2/file.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package gotgbot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// InputFile (https://core.telegram.org/bots/api#inputfile)
|
||||
//
|
||||
// This object represents the contents of a file to be uploaded.
|
||||
// Must be posted using multipart/form-data in the usual way that files are uploaded via the browser.
|
||||
type InputFile interface {
|
||||
InputFileOrString
|
||||
justFiles()
|
||||
}
|
||||
|
||||
// InputFileOrString (https://core.telegram.org/bots/api#inputfile)
|
||||
//
|
||||
// This object represents the contents of a file to be uploaded, or a publicly accessible URL to be reused.
|
||||
// Files must be posted using multipart/form-data in the usual way that files are uploaded via the browser.
|
||||
type InputFileOrString interface {
|
||||
Attach(name string, data map[string]FileReader) error
|
||||
getValue() string
|
||||
}
|
||||
|
||||
var (
|
||||
_ InputFileOrString = &FileReader{}
|
||||
_ InputFile = &FileReader{}
|
||||
)
|
||||
|
||||
type FileReader struct {
|
||||
Name string
|
||||
Data io.Reader
|
||||
|
||||
value string
|
||||
}
|
||||
|
||||
func (f *FileReader) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(f.getValue())
|
||||
}
|
||||
|
||||
var ErrAttachmentKeyAlreadyExists = errors.New("key already exists")
|
||||
|
||||
func (f *FileReader) justFiles() {}
|
||||
|
||||
func (f *FileReader) Attach(key string, data map[string]FileReader) error {
|
||||
if f.Data == nil {
|
||||
// if no data, this must be a string; nothing to "attach".
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := data[key]; ok {
|
||||
return ErrAttachmentKeyAlreadyExists
|
||||
}
|
||||
f.value = "attach://" + key
|
||||
data[key] = *f
|
||||
return nil
|
||||
}
|
||||
|
||||
// getValue returns the file attach reference for the relevant multipart form.
|
||||
// Make sure to only call getValue after having called Attach(), to ensure any files have been included.
|
||||
func (f *FileReader) getValue() string {
|
||||
return f.value
|
||||
}
|
||||
|
||||
// InputFileByURL is used to send a file on the internet via a publicly accessible HTTP URL.
|
||||
func InputFileByURL(url string) InputFileOrString {
|
||||
return &FileReader{value: url}
|
||||
}
|
||||
|
||||
// InputFileByID is used to send a file that is already present on telegram's servers, using its telegram file_id.
|
||||
func InputFileByID(fileID string) InputFileOrString {
|
||||
return &FileReader{value: fileID}
|
||||
}
|
||||
|
||||
// InputFileByReader is used to send a file by a reader interface; such as a filehandle from os.Open(), or from a byte
|
||||
// buffer.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// f, err := os.Open("some_file.go")
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to open file: %w", err)
|
||||
// }
|
||||
//
|
||||
// m, err := b.SendDocument(<chat_id>, gotgbot.InputFileByReader("source.go", f), nil)
|
||||
//
|
||||
// Or
|
||||
//
|
||||
// m, err := b.SendDocument(<chat_id>, gotgbot.InputFileByReader("file.txt", strings.NewReader("Some file contents")), nil)
|
||||
func InputFileByReader(name string, r io.Reader) InputFile {
|
||||
return &FileReader{Name: name, Data: r}
|
||||
}
|
||||
38
vendor/github.com/PaulSonOfLars/gotgbot/v2/formatting.go
generated
vendored
38
vendor/github.com/PaulSonOfLars/gotgbot/v2/formatting.go
generated
vendored
@@ -15,25 +15,27 @@ var mdMap = map[string]string{
|
||||
}
|
||||
|
||||
var mdV2Map = map[string]string{
|
||||
"bold": "*",
|
||||
"italic": "_",
|
||||
"code": "`",
|
||||
"pre": "```",
|
||||
"underline": "__",
|
||||
"strikethrough": "~",
|
||||
"spoiler": "||",
|
||||
"blockquote": ">",
|
||||
"bold": "*",
|
||||
"italic": "_",
|
||||
"code": "`",
|
||||
"pre": "```",
|
||||
"underline": "__",
|
||||
"strikethrough": "~",
|
||||
"spoiler": "||",
|
||||
"blockquote": ">",
|
||||
"expandable_blockquote": "**>",
|
||||
}
|
||||
|
||||
var htmlMap = map[string]string{
|
||||
"bold": "b",
|
||||
"italic": "i",
|
||||
"code": "code",
|
||||
"pre": "pre",
|
||||
"underline": "u",
|
||||
"strikethrough": "s",
|
||||
"spoiler": "span class=\"tg-spoiler\"",
|
||||
"blockquote": "blockquote",
|
||||
"bold": "b",
|
||||
"italic": "i",
|
||||
"code": "code",
|
||||
"pre": "pre",
|
||||
"underline": "u",
|
||||
"strikethrough": "s",
|
||||
"spoiler": "span class=\"tg-spoiler\"",
|
||||
"blockquote": "blockquote",
|
||||
"expandable_blockquote": "blockquote expandable",
|
||||
}
|
||||
|
||||
// OriginalMD gets the original markdown formatting of a message text.
|
||||
@@ -209,6 +211,8 @@ func writeFinalHTML(data []uint16, ent MessageEntity, start int64, cntnt string)
|
||||
return prevText + `<a href="` + ent.Url + `">` + cntnt + "</a>"
|
||||
case "blockquote":
|
||||
return prevText + `<blockquote>` + cntnt + "</blockquote>"
|
||||
case "expandable_blockquote":
|
||||
return prevText + `<blockquote expandable>` + cntnt + "</blockquote>"
|
||||
default:
|
||||
return prevText + cntnt
|
||||
}
|
||||
@@ -243,6 +247,8 @@ func writeFinalMarkdownV2(data []uint16, ent MessageEntity, start int64, cntnt s
|
||||
return prevText + pre + "[" + cleanCntnt + "](" + ent.Url + ")" + post
|
||||
case "blockquote":
|
||||
return prevText + pre + ">" + strings.Join(strings.Split(cleanCntnt, "\n"), "\n>") + post
|
||||
case "expandable_blockquote":
|
||||
return prevText + pre + "**>" + strings.Join(strings.Split(cleanCntnt, "\n"), "\n>") + "||" + post
|
||||
default:
|
||||
return prevText + cntnt
|
||||
}
|
||||
|
||||
19
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_consts.go
generated
vendored
19
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_consts.go
generated
vendored
@@ -20,6 +20,7 @@ const (
|
||||
UpdateTypeCallbackQuery = "callback_query"
|
||||
UpdateTypeShippingQuery = "shipping_query"
|
||||
UpdateTypePreCheckoutQuery = "pre_checkout_query"
|
||||
UpdateTypePurchasedPaidMedia = "purchased_paid_media"
|
||||
UpdateTypePoll = "poll"
|
||||
UpdateTypePollAnswer = "poll_answer"
|
||||
UpdateTypeMyChatMember = "my_chat_member"
|
||||
@@ -77,6 +78,9 @@ func (u Update) GetType() string {
|
||||
case u.PreCheckoutQuery != nil:
|
||||
return UpdateTypePreCheckoutQuery
|
||||
|
||||
case u.PurchasedPaidMedia != nil:
|
||||
return UpdateTypePurchasedPaidMedia
|
||||
|
||||
case u.Poll != nil:
|
||||
return UpdateTypePoll
|
||||
|
||||
@@ -111,6 +115,21 @@ const (
|
||||
ParseModeNone = ""
|
||||
)
|
||||
|
||||
// The consts listed below represent all the chat action options that can be sent to telegram.
|
||||
const (
|
||||
ChatActionTyping = "typing"
|
||||
ChatActionUploadPhoto = "upload_photo"
|
||||
ChatActionRecordVideo = "record_video"
|
||||
ChatActionUploadVideo = "upload_video"
|
||||
ChatActionRecordVoice = "record_voice"
|
||||
ChatActionUploadVoice = "upload_voice"
|
||||
ChatActionUploadDocument = "upload_document"
|
||||
ChatActionChooseSticker = "choose_sticker"
|
||||
ChatActionFindLocation = "find_location"
|
||||
ChatActionRecordVideoNote = "record_video_note"
|
||||
ChatActionUploadVideoNote = "upload_video_note"
|
||||
)
|
||||
|
||||
// The consts listed below represent all the sticker types that can be obtained from telegram.
|
||||
const (
|
||||
StickerTypeRegular = "regular"
|
||||
|
||||
10
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_helpers.go
generated
vendored
10
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_helpers.go
generated
vendored
@@ -33,6 +33,11 @@ func (c Chat) CreateInviteLink(b *Bot, opts *CreateChatInviteLinkOpts) (*ChatInv
|
||||
return b.CreateChatInviteLink(c.Id, opts)
|
||||
}
|
||||
|
||||
// CreateSubscriptionInviteLink Helper method for Bot.CreateChatSubscriptionInviteLink.
|
||||
func (c Chat) CreateSubscriptionInviteLink(b *Bot, subscriptionPeriod int64, subscriptionPrice int64, opts *CreateChatSubscriptionInviteLinkOpts) (*ChatInviteLink, error) {
|
||||
return b.CreateChatSubscriptionInviteLink(c.Id, subscriptionPeriod, subscriptionPrice, opts)
|
||||
}
|
||||
|
||||
// DeclineJoinRequest Helper method for Bot.DeclineChatJoinRequest.
|
||||
func (c Chat) DeclineJoinRequest(b *Bot, userId int64, opts *DeclineChatJoinRequestOpts) (bool, error) {
|
||||
return b.DeclineChatJoinRequest(c.Id, userId, opts)
|
||||
@@ -53,6 +58,11 @@ func (c Chat) EditInviteLink(b *Bot, inviteLink string, opts *EditChatInviteLink
|
||||
return b.EditChatInviteLink(c.Id, inviteLink, opts)
|
||||
}
|
||||
|
||||
// EditSubscriptionInviteLink Helper method for Bot.EditChatSubscriptionInviteLink.
|
||||
func (c Chat) EditSubscriptionInviteLink(b *Bot, inviteLink string, opts *EditChatSubscriptionInviteLinkOpts) (*ChatInviteLink, error) {
|
||||
return b.EditChatSubscriptionInviteLink(c.Id, inviteLink, opts)
|
||||
}
|
||||
|
||||
// ExportInviteLink Helper method for Bot.ExportChatInviteLink.
|
||||
func (c Chat) ExportInviteLink(b *Bot, opts *ExportChatInviteLinkOpts) (string, error) {
|
||||
return b.ExportChatInviteLink(c.Id, opts)
|
||||
|
||||
2022
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go
generated
vendored
2022
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1819
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go
generated
vendored
1819
vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go
generated
vendored
File diff suppressed because it is too large
Load Diff
100
vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go
generated
vendored
100
vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go
generated
vendored
@@ -21,9 +21,7 @@ const (
|
||||
|
||||
type BotClient interface {
|
||||
// RequestWithContext submits a POST HTTP request a bot API instance.
|
||||
RequestWithContext(ctx context.Context, token string, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error)
|
||||
// TimeoutContext calculates the required timeout contect required given the passed RequestOpts, and any default opts defined by the BotClient.
|
||||
TimeoutContext(opts *RequestOpts) (context.Context, context.CancelFunc)
|
||||
RequestWithContext(ctx context.Context, token string, method string, params map[string]string, data map[string]FileReader, opts *RequestOpts) (json.RawMessage, error)
|
||||
// GetAPIURL gets the URL of the API either in use by the bot or defined in the request opts.
|
||||
GetAPIURL(opts *RequestOpts) string
|
||||
// FileURL gets the URL of a file at the API address that the bot is interacting with.
|
||||
@@ -74,24 +72,6 @@ func (t *TelegramError) Error() string {
|
||||
return fmt.Sprintf("unable to %s: %s", t.Method, t.Description)
|
||||
}
|
||||
|
||||
type NamedReader interface {
|
||||
Name() string
|
||||
io.Reader
|
||||
}
|
||||
|
||||
type NamedFile struct {
|
||||
File io.Reader
|
||||
FileName string
|
||||
}
|
||||
|
||||
func (nf NamedFile) Read(p []byte) (n int, err error) {
|
||||
return nf.File.Read(p)
|
||||
}
|
||||
|
||||
func (nf NamedFile) Name() string {
|
||||
return nf.FileName
|
||||
}
|
||||
|
||||
// RequestOpts defines any request-specific options used to interact with the telegram API.
|
||||
type RequestOpts struct {
|
||||
// Timeout for the HTTP request to the telegram API.
|
||||
@@ -100,38 +80,45 @@ type RequestOpts struct {
|
||||
APIURL string
|
||||
}
|
||||
|
||||
// TimeoutContext returns the appropriate context for the current settings.
|
||||
func (bot *BaseBotClient) TimeoutContext(opts *RequestOpts) (context.Context, context.CancelFunc) {
|
||||
// getTimeoutContext returns the appropriate context for the current settings.
|
||||
func (bot *BaseBotClient) getTimeoutContext(parentCtx context.Context, opts *RequestOpts) (context.Context, context.CancelFunc) {
|
||||
if parentCtx == nil {
|
||||
parentCtx = context.Background()
|
||||
}
|
||||
|
||||
if opts != nil {
|
||||
ctx, cancelFunc := timeoutFromOpts(opts)
|
||||
ctx, cancelFunc := timeoutFromOpts(parentCtx, opts)
|
||||
if ctx != nil {
|
||||
return ctx, cancelFunc
|
||||
}
|
||||
}
|
||||
|
||||
if bot.DefaultRequestOpts != nil {
|
||||
ctx, cancelFunc := timeoutFromOpts(bot.DefaultRequestOpts)
|
||||
ctx, cancelFunc := timeoutFromOpts(parentCtx, bot.DefaultRequestOpts)
|
||||
if ctx != nil {
|
||||
return ctx, cancelFunc
|
||||
}
|
||||
}
|
||||
|
||||
return context.WithTimeout(context.Background(), DefaultTimeout)
|
||||
return context.WithTimeout(parentCtx, DefaultTimeout)
|
||||
}
|
||||
|
||||
func timeoutFromOpts(opts *RequestOpts) (context.Context, context.CancelFunc) {
|
||||
func timeoutFromOpts(parentCtx context.Context, opts *RequestOpts) (context.Context, context.CancelFunc) {
|
||||
// nothing? no timeout.
|
||||
if opts == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if parentCtx == nil {
|
||||
parentCtx = context.Background()
|
||||
}
|
||||
|
||||
if opts.Timeout > 0 {
|
||||
// > 0 timeout defined.
|
||||
return context.WithTimeout(context.Background(), opts.Timeout)
|
||||
return context.WithTimeout(parentCtx, opts.Timeout)
|
||||
|
||||
} else if opts.Timeout < 0 {
|
||||
// < 0 no timeout; infinite.
|
||||
return context.Background(), func() {}
|
||||
return parentCtx, func() {}
|
||||
}
|
||||
// 0 == nothing defined, use defaults.
|
||||
return nil, nil
|
||||
@@ -142,28 +129,40 @@ func timeoutFromOpts(opts *RequestOpts) (context.Context, context.CancelFunc) {
|
||||
// - method: the telegram API method to call.
|
||||
// - params: map of parameters to be sending to the telegram API. eg: chat_id, user_id, etc.
|
||||
// - data: map of any files to be sending to the telegram API.
|
||||
// - opts: request opts to use. Note: Timeout opts are ignored when used in RequestWithContext. Timeout handling is the
|
||||
// responsibility of the caller/context owner.
|
||||
func (bot *BaseBotClient) RequestWithContext(ctx context.Context, token string, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) {
|
||||
b := &bytes.Buffer{}
|
||||
// - opts: request opts to use.
|
||||
func (bot *BaseBotClient) RequestWithContext(parentCtx context.Context, token string, method string, params map[string]string, data map[string]FileReader, opts *RequestOpts) (json.RawMessage, error) {
|
||||
ctx, cancel := bot.getTimeoutContext(parentCtx, opts)
|
||||
defer cancel()
|
||||
|
||||
var requestBody io.Reader
|
||||
|
||||
var contentType string
|
||||
// Check if there are any files to upload. If yes, use multipart; else, use JSON.
|
||||
if len(data) > 0 {
|
||||
var err error
|
||||
contentType, err = fillBuffer(b, params, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fill buffer with parameters and file data: %w", err)
|
||||
}
|
||||
pr, pw := io.Pipe()
|
||||
defer pr.Close() // avoid writer goroutine leak
|
||||
mw := multipart.NewWriter(pw)
|
||||
contentType = mw.FormDataContentType()
|
||||
requestBody = pr
|
||||
// Write the request data asynchronously from another goroutine
|
||||
// to the multipart.Writer which will be piped into the pipe reader
|
||||
// which is tied to the request to be sent
|
||||
go func() {
|
||||
writerError := fillBuffer(mw, params, data)
|
||||
// Close the writer with error of multipart writer.
|
||||
// If the error is nil, this will act just like pw.Close()
|
||||
_ = pw.CloseWithError(writerError)
|
||||
}()
|
||||
} else {
|
||||
contentType = "application/json"
|
||||
err := json.NewEncoder(b).Encode(params)
|
||||
bodyBytes, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encode parameters as JSON: %w", err)
|
||||
}
|
||||
requestBody = bytes.NewReader(bodyBytes)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, bot.methodEndpoint(token, method, opts), b)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, bot.methodEndpoint(token, method, opts), requestBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build POST request to %s: %w", method, err)
|
||||
}
|
||||
@@ -194,38 +193,37 @@ func (bot *BaseBotClient) RequestWithContext(ctx context.Context, token string,
|
||||
return r.Result, nil
|
||||
}
|
||||
|
||||
func fillBuffer(b *bytes.Buffer, params map[string]string, data map[string]NamedReader) (string, error) {
|
||||
w := multipart.NewWriter(b)
|
||||
|
||||
// Fill the buffer of multipart.Writer with data which is going to be sent.
|
||||
func fillBuffer(w *multipart.Writer, params map[string]string, data map[string]FileReader) error {
|
||||
for k, v := range params {
|
||||
err := w.WriteField(k, v)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to write multipart field %s with value %s: %w", k, v, err)
|
||||
return fmt.Errorf("failed to write multipart field %s with value %s: %w", k, v, err)
|
||||
}
|
||||
}
|
||||
|
||||
for field, file := range data {
|
||||
fileName := file.Name()
|
||||
fileName := file.Name
|
||||
if fileName == "" {
|
||||
fileName = field
|
||||
}
|
||||
|
||||
part, err := w.CreateFormFile(field, fileName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create form file for field %s and fileName %s: %w", field, fileName, err)
|
||||
return fmt.Errorf("failed to create form file for field %s and fileName %s: %w", field, fileName, err)
|
||||
}
|
||||
|
||||
_, err = io.Copy(part, file)
|
||||
_, err = io.Copy(part, file.Data)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to copy file contents of field %s to form: %w", field, err)
|
||||
return fmt.Errorf("failed to copy file contents of field %s to form: %w", field, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := w.Close(); err != nil {
|
||||
return "", fmt.Errorf("failed to close multipart form writer: %w", err)
|
||||
return fmt.Errorf("failed to close multipart form writer: %w", err)
|
||||
}
|
||||
|
||||
return w.FormDataContentType(), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAPIURL returns the currently used API endpoint.
|
||||
|
||||
2
vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit
generated
vendored
2
vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit
generated
vendored
@@ -1 +1 @@
|
||||
68843d1ae456b90a494bfee92253f30a8204b2a7
|
||||
15b6cd15658668b7017f3c069e27405ca4f4428e
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -22,7 +22,7 @@ github.com/Microsoft/go-winio/internal/fs
|
||||
github.com/Microsoft/go-winio/internal/socket
|
||||
github.com/Microsoft/go-winio/internal/stringbuffer
|
||||
github.com/Microsoft/go-winio/pkg/guid
|
||||
# github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27
|
||||
# github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30
|
||||
## explicit; go 1.19
|
||||
github.com/PaulSonOfLars/gotgbot/v2
|
||||
# github.com/PuerkitoBio/goquery v1.8.1
|
||||
|
||||
Reference in New Issue
Block a user