From 3b840126b2033a103a16a07f0602274f19e6c6c9 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Wed, 25 Oct 2017 19:48:53 +0500 Subject: [PATCH] :construction: Save work-in-progress state --- new_helpers.go | 4 +- request.go | 39 ++++++++++++++++++++ send_sticker.go | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ set_webhook.go | 33 +---------------- telegram.go | 69 ---------------------------------- upload.go | 88 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 228 insertions(+), 103 deletions(-) create mode 100644 request.go create mode 100644 send_sticker.go create mode 100644 upload.go diff --git a/new_helpers.go b/new_helpers.go index 2c701fe..7d14eb1 100644 --- a/new_helpers.go +++ b/new_helpers.go @@ -358,7 +358,7 @@ func (bot *Bot) NewLongPollingChannel(params *GetUpdatesParameters) UpdatesChann return channel } -func NewWebhookChannel(set, listen, serve string, params *GetUpdatesParameters) UpdatesChannel { +func NewWebhookChannel(listen, serve string, params *GetUpdatesParameters) UpdatesChannel { if params == nil { params = &GetUpdatesParameters{ Offset: 0, @@ -377,7 +377,7 @@ func NewWebhookChannel(set, listen, serve string, params *GetUpdatesParameters) channel <- update } }); err != nil { - log.Fatalln(err.Error()) + panic(err.Error()) } }() diff --git a/request.go b/request.go new file mode 100644 index 0000000..a7584dc --- /dev/null +++ b/request.go @@ -0,0 +1,39 @@ +package telegram + +import ( + "errors" + "fmt" + + json "github.com/pquerna/ffjson/ffjson" + http "github.com/valyala/fasthttp" +) + +func (bot *Bot) request(dst []byte, method string, args *http.Args) (*Response, error) { + requestURI := fmt.Sprintf(APIEndpoint, bot.AccessToken, method) + if args != nil { + requestURI += fmt.Sprint("?", args.String()) + } + + var req http.Request + var resp http.Response + + req.Header.SetMethod("POST") + req.Header.SetContentType("application/json") + req.SetRequestURI(requestURI) + req.SetBody(dst) + + if err := http.Do(&req, &resp); err != nil { + return nil, err + } + + var data Response + if err := json.Unmarshal(resp.Body(), &data); err != nil { + return nil, err + } + + if !data.Ok { + return nil, errors.New(data.Description) + } + + return &data, nil +} diff --git a/send_sticker.go b/send_sticker.go new file mode 100644 index 0000000..09f99ca --- /dev/null +++ b/send_sticker.go @@ -0,0 +1,98 @@ +package telegram + +/* +import ( + "bytes" + "errors" + "fmt" + "io" + "mime/multipart" + "os" + "strconv" + "strings" + + json "github.com/pquerna/ffjson/ffjson" + http "github.com/valyala/fasthttp" +) + +type SendStickerParameters struct { + // Unique identifier for the target chat + ChatID int64 `json:"chat_id"` + + // Sticker 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 .webp file from the Internet, or upload a new one using + // multipart/form-data. + Sticker *InputFile `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 *ReplyMarkup `json:"reply_markup,omitempty"` +} + +func NewSticker(chatID int64, sticker interface{}) *SendStickerParameters { + params := &SendStickerParameters{ChatID: chatID} + + if sticker != nil { + var input InputFile = file + params.Sticker = &input + } + + return params +} + +// SendSticker send .webp stickers. On success, the sent Message is returned. +func (bot *Bot) SendSticker(params *SendStickerParameters) (*Message, error) { + var args http.Args + args.Add("chat_id", params.ChatID) + args.Add("disable_notification", strconv.FormatBool(params.DisableNotification)) + + if params.ReplyToMessageID > 0 { + args.Add("reply_to_message_id", strconv.Itoa(params.ReplyToMessageID)) + } + + var buffer bytes.Buffer + multi := multipart.NewWriter(&buffer) + + sticker := *params.Sticker + switch file := sticker.(type) { + case string: + f, err := os.Open(file) + if err != nil { + return false, err + } + defer f.Close() + + formFile, err := multi.CreateFormFile("sticker", f.Name()) + if err != nil { + return false, err + } + if _, err = io.Copy(formFile, f); err != nil { + return false, err + } + multi.Close() + case []byte: + file + bytes.NewReader(file). + default: + return false, errors.New("use string only (for current version of go-telegram)") + } + + resp, err := bot.upload(buffer.Bytes(), multi.Boundary(), "setWebhook", &args) + if err != nil { + return false, err + } + + var data bool + err = json.Unmarshal(*resp.Result, &data) + return data, err +} +*/ diff --git a/set_webhook.go b/set_webhook.go index 706fe2a..59da3fc 100644 --- a/set_webhook.go +++ b/set_webhook.go @@ -1,12 +1,7 @@ package telegram import ( - "bytes" - "errors" "fmt" - "io" - "mime/multipart" - "os" "strconv" "strings" @@ -73,33 +68,7 @@ func (bot *Bot) SetWebhook(params *SetWebhookParameters) (bool, error) { args.Add("max_connections", strconv.Itoa(params.MaxConnections)) } - var buffer bytes.Buffer - multi := multipart.NewWriter(&buffer) - - if params.Certificate != nil { - cert := *params.Certificate - switch file := cert.(type) { - case string: - f, err := os.Open(file) - if err != nil { - return false, err - } - defer f.Close() - - formFile, err := multi.CreateFormFile("certificate", f.Name()) - if err != nil { - return false, err - } - if _, err = io.Copy(formFile, f); err != nil { - return false, err - } - multi.Close() - default: - return false, errors.New("use string only (for current version of go-telegram)") - } - } - - resp, err := bot.upload(buffer.Bytes(), multi.Boundary(), "setWebhook", &args) + resp, err := bot.upload(*params.Certificate, "certificate", "cert.pem", "setWebhook", &args) if err != nil { return false, err } diff --git a/telegram.go b/telegram.go index 23c53f5..1b6fa67 100644 --- a/telegram.go +++ b/telegram.go @@ -1,76 +1,7 @@ // Version of the bot API: 3.4 (October 11, 2017) package telegram -import ( - "errors" - "fmt" - - json "github.com/pquerna/ffjson/ffjson" - http "github.com/valyala/fasthttp" -) - const ( APIEndpoint = "https://api.telegram.org/bot%s/%s" FileEndpoind = "https://api.telegram.org/file/bot%s/%s" ) - -func (bot *Bot) request(dst []byte, method string, args *http.Args) (*Response, error) { - requestURI := fmt.Sprintf(APIEndpoint, bot.AccessToken, method) - if args != nil { - requestURI += fmt.Sprint("?", args.String()) - } - - var req http.Request - var resp http.Response - - req.Header.SetMethod("POST") - req.Header.SetContentType("application/json") - req.SetRequestURI(requestURI) - req.SetBody(dst) - - if err := http.Do(&req, &resp); err != nil { - return nil, err - } - - var data Response - if err := json.Unmarshal(resp.Body(), &data); err != nil { - return nil, err - } - - if !data.Ok { - return nil, errors.New(data.Description) - } - - return &data, nil -} - -func (bot *Bot) upload(dst []byte, boundary, method string, args *http.Args) (*Response, error) { - requestURI := fmt.Sprintf(APIEndpoint, bot.AccessToken, method) - if args != nil { - requestURI += fmt.Sprint("?", args.String()) - } - - var req http.Request - var resp http.Response - - req.Header.SetMethod("POST") - req.Header.SetContentType("multipart/form-data") - req.Header.SetMultipartFormBoundary(boundary) - req.SetRequestURI(requestURI) - req.SetBody(dst) - - if err := http.Do(&req, &resp); err != nil { - return nil, err - } - - var data Response - if err := json.Unmarshal(resp.Body(), &data); err != nil { - return nil, err - } - - if !data.Ok { - return nil, errors.New(data.Description) - } - - return &data, nil -} diff --git a/upload.go b/upload.go new file mode 100644 index 0000000..bb79b87 --- /dev/null +++ b/upload.go @@ -0,0 +1,88 @@ +package telegram + +import ( + "bytes" + "errors" + "fmt" + "io" + "mime/multipart" + "net/url" + "os" + + json "github.com/pquerna/ffjson/ffjson" + http "github.com/valyala/fasthttp" +) + +// There are three ways to send files (photos, stickers, audio, media, etc.): +// +// 1. If the file is already stored somewhere on the Telegram servers, you don't need to reupload it: each file object has a file_id field, simply pass this file_id as a parameter instead of uploading. There are no limits for files sent this way. +// 2. Provide Telegram with an HTTP URL for the file to be sent. Telegram will download and send the file. 5 MB max size for photos and 20 MB max for other types of content. +// 3. Post the file using multipart/form-data in the usual way that files are uploaded via the browser. 10 MB max size for photos, 50 MB for other files. +func (bot *Bot) upload(file InputFile, fieldName, fileName, method string, args *http.Args) (*Response, error) { + var buffer bytes.Buffer + multi := multipart.NewWriter(&buffer) + defer multi.Close() + + switch source := file.(type) { + case string: + f, err := os.Open(source) + if err != nil { + return nil, err + } + defer f.Close() + + formFile, err := multi.CreateFormFile(fieldName, f.Name()) + if err != nil { + return nil, err + } + if _, err = io.Copy(formFile, f); err != nil { + return nil, err + } + case []byte: + formFile, err := multi.CreateFormFile(fieldName, fileName) + if err != nil { + return nil, err + } + if _, err = io.Copy(formFile, bytes.NewReader(source)); err != nil { + return nil, err + } + case *url.URL: + if err := multi.WriteField(fieldName, source.String()); err != nil { + return nil, err + } + case io.Reader: + multi.CreateFormFile(fieldName, fileName) + default: + return nil, errors.New("bad file type") + } + + requestURI := fmt.Sprintf(APIEndpoint, bot.AccessToken, method) + if args != nil { + requestURI += fmt.Sprint("?", args.String()) + } + + var req http.Request + var resp http.Response + + req.Header.SetMethod("POST") + req.Header.SetContentType("multipart/form-data") + req.Header.SetMultipartFormBoundary(multi.Boundary()) + args.WriteTo(req.BodyWriter()) + req.SetRequestURI(requestURI) + req.SetBody(buffer.Bytes()) + + if err := http.Do(&req, &resp); err != nil { + return nil, err + } + + var data Response + if err := json.Unmarshal(resp.Body(), &data); err != nil { + return nil, err + } + + if !data.Ok { + return nil, errors.New(data.Description) + } + + return &data, nil +}