chat actions and file uploading; v0.3.7
This commit is contained in:
117
uploader.go
117
uploader.go
@@ -2,12 +2,12 @@ package laniakea
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Uploader struct {
|
||||
@@ -17,43 +17,120 @@ type Uploader struct {
|
||||
func NewUploader(bot *Bot) *Uploader {
|
||||
return &Uploader{bot: bot}
|
||||
}
|
||||
func (u *Uploader) UploadPhoto(chatId int, data []byte) error {
|
||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendPhoto", u.bot.token)
|
||||
|
||||
type UploaderFileType string
|
||||
|
||||
const (
|
||||
UploaderPhotoType UploaderFileType = "photo"
|
||||
UploaderVideoType UploaderFileType = "video"
|
||||
UploaderAudioType UploaderFileType = "audio"
|
||||
UploaderDocumentType UploaderFileType = "document"
|
||||
UploaderVoiceType UploaderFileType = "voice"
|
||||
UploaderVideoNoteType UploaderFileType = "video_note"
|
||||
)
|
||||
|
||||
type UploaderFile struct {
|
||||
filename string
|
||||
data []byte
|
||||
t UploaderFileType
|
||||
}
|
||||
|
||||
func NewUploaderFile(name string, data []byte) UploaderFile {
|
||||
t := uploaderTypeByExt(name)
|
||||
return UploaderFile{filename: name, data: data, t: t}
|
||||
}
|
||||
|
||||
// SetType used when auto-detect failed. I.e. you sending a voice message, but it detects as audio
|
||||
func (f UploaderFile) SetType(t UploaderFileType) UploaderFile {
|
||||
f.t = t
|
||||
return f
|
||||
}
|
||||
|
||||
type UploaderRequest[R, P any] struct {
|
||||
method string
|
||||
file UploaderFile
|
||||
params P
|
||||
}
|
||||
|
||||
func NewUploaderRequest[R, P any](method string, file UploaderFile, params P) UploaderRequest[R, P] {
|
||||
return UploaderRequest[R, P]{method, file, params}
|
||||
}
|
||||
|
||||
func (u UploaderRequest[R, P]) Do(bot *Bot) (*R, error) {
|
||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/%s", bot.token, u.method)
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
w := multipart.NewWriter(buf)
|
||||
defer w.Close()
|
||||
err := w.WriteField("chat_id", strconv.Itoa(chatId))
|
||||
|
||||
fw, err := w.CreateFormFile(string(u.file.t), u.file.filename)
|
||||
if err != nil {
|
||||
return err
|
||||
w.Close()
|
||||
return nil, err
|
||||
}
|
||||
fw, err := w.CreateFormFile("photo", "photo.jpg")
|
||||
_, err = fw.Write(u.file.data)
|
||||
if err != nil {
|
||||
return err
|
||||
w.Close()
|
||||
return nil, err
|
||||
}
|
||||
_, err = fw.Write(data)
|
||||
err = Encode(w, u.params)
|
||||
if err != nil {
|
||||
return err
|
||||
w.Close()
|
||||
return nil, err
|
||||
}
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
bot.logger.Debugln("UPLOADER REQ", u.method)
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
bot.logger.Debugln("UPLOADER RES", u.method, string(body))
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("[%d] %s", res.StatusCode, string(body))
|
||||
}
|
||||
|
||||
response := new(ApiResponse[*R])
|
||||
err = json.Unmarshal(body, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !response.Ok {
|
||||
return nil, fmt.Errorf("[%d] %s", response.ErrorCode, response.Description)
|
||||
}
|
||||
return response.Result, nil
|
||||
}
|
||||
|
||||
func (u *Uploader) UploadPhoto(file UploaderFile, params SendPhotoBaseP) (*Message, error) {
|
||||
req := NewUploaderRequest[Message]("sendPhoto", file, params)
|
||||
return req.Do(u.bot)
|
||||
}
|
||||
|
||||
func uploaderTypeByExt(filename string) UploaderFileType {
|
||||
ext := filepath.Ext(filename)
|
||||
switch ext {
|
||||
case ".jpg", ".jpeg", ".png", ".webp", ".bmp":
|
||||
return UploaderPhotoType
|
||||
case ".mp4":
|
||||
return UploaderVideoType
|
||||
case ".mp3", ".m4a":
|
||||
return UploaderAudioType
|
||||
case ".ogg":
|
||||
return UploaderVoiceType
|
||||
default:
|
||||
return UploaderDocumentType
|
||||
}
|
||||
log.Println("upload", string(body))
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user