merge upstream
commit
ae7c1b4e22
37
methods.go
37
methods.go
|
@ -1,18 +1,17 @@
|
|||
package tgbotapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/technoweenie/multipartstreamer"
|
||||
)
|
||||
|
||||
// Telegram constants
|
||||
|
@ -193,46 +192,32 @@ func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse,
|
|||
//
|
||||
// Requires the parameter to hold the file not be in the params.
|
||||
func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldname string, filename string) (APIResponse, error) {
|
||||
var b bytes.Buffer
|
||||
w := multipart.NewWriter(&b)
|
||||
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fw, err := w.CreateFormFile(fieldname, filename)
|
||||
fi, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
|
||||
if _, err = io.Copy(fw, f); err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
ms := multipartstreamer.New()
|
||||
ms.WriteFields(params)
|
||||
ms.WriteReader(fieldname, f.Name(), fi.Size(), f)
|
||||
|
||||
for key, val := range params {
|
||||
if fw, err = w.CreateFormField(key); err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
|
||||
if _, err = fw.Write([]byte(val)); err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
}
|
||||
|
||||
w.Close()
|
||||
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf(APIEndpoint, bot.Token, endpoint), &b)
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf(APIEndpoint, bot.Token, endpoint), nil)
|
||||
ms.SetupRequest(req)
|
||||
if err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
|
||||
res, err := bot.Client.Do(req)
|
||||
if err != nil {
|
||||
return APIResponse{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
bytes, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
|
@ -408,6 +393,7 @@ func (bot *BotAPI) SendPhoto(config PhotoConfig) (Message, error) {
|
|||
// when the fields title and performer are both empty
|
||||
// and the mime-type of the file to be sent is not audio/mpeg,
|
||||
// the file must be in an .ogg file encoded with OPUS.
|
||||
// You may use the tgutils.EncodeAudio func to assist you with this, if needed.
|
||||
//
|
||||
// Requires ChatID and FileID OR FilePath.
|
||||
// ReplyToMessageID and ReplyMarkup are optional.
|
||||
|
@ -561,6 +547,7 @@ func (bot *BotAPI) SendDocument(config DocumentConfig) (Message, error) {
|
|||
|
||||
// SendVoice sends or uploads a playable voice to a chat.
|
||||
// If using a file, the file must be encoded as an .ogg with OPUS.
|
||||
// You may use the tgutils.EncodeAudio func to assist you with this, if needed.
|
||||
//
|
||||
// Requires ChatID and FileID OR FilePath.
|
||||
// ReplyToMessageID and ReplyMarkup are optional.
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
// Package tgutils provides extra functions to make certain tasks easier.
|
||||
package tgutils
|
||||
|
||||
import (
|
||||
"github.com/syfaro/telegram-bot-api"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var rand uint32
|
||||
var randmu sync.Mutex
|
||||
|
||||
func reseed() uint32 {
|
||||
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
|
||||
}
|
||||
|
||||
func nextSuffix() string {
|
||||
randmu.Lock()
|
||||
r := rand
|
||||
if r == 0 {
|
||||
r = reseed()
|
||||
}
|
||||
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||
rand = r
|
||||
randmu.Unlock()
|
||||
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||
}
|
||||
|
||||
// this function ripped from ioutils.TempFile, except with a suffix, instead of prefix.
|
||||
func tempFileWithSuffix(dir, suffix string) (f *os.File, err error) {
|
||||
if dir == "" {
|
||||
dir = os.TempDir()
|
||||
}
|
||||
|
||||
nconflict := 0
|
||||
for i := 0; i < 10000; i++ {
|
||||
name := filepath.Join(dir, nextSuffix()+suffix)
|
||||
f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
||||
if os.IsExist(err) {
|
||||
if nconflict++; nconflict > 10 {
|
||||
randmu.Lock()
|
||||
rand = reseed()
|
||||
randmu.Unlock()
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EncodeAudio takes a file and attempts to convert it to a .ogg for Telegram.
|
||||
// It then updates the path to the audio file in the AudioConfig.
|
||||
//
|
||||
// This function requires ffmpeg and opusenc to be installed on the system!
|
||||
func EncodeAudio(audio *tgbotapi.AudioConfig) error {
|
||||
f, err := tempFileWithSuffix(os.TempDir(), "_tgutils.ogg")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
ffmpegArgs := []string{
|
||||
"-i",
|
||||
audio.FilePath,
|
||||
"-f",
|
||||
"wav",
|
||||
"-",
|
||||
}
|
||||
|
||||
opusArgs := []string{
|
||||
"--bitrate",
|
||||
"256",
|
||||
"-",
|
||||
f.Name(),
|
||||
}
|
||||
|
||||
c1 := exec.Command("ffmpeg", ffmpegArgs...)
|
||||
c2 := exec.Command("opusenc", opusArgs...)
|
||||
|
||||
c2.Stdin, _ = c1.StdoutPipe()
|
||||
c2.Stdout = os.Stdout
|
||||
c2.Start()
|
||||
c1.Run()
|
||||
c2.Wait()
|
||||
|
||||
return nil
|
||||
}
|
2
types.go
2
types.go
|
@ -80,7 +80,7 @@ type Message struct {
|
|||
NewChatParticipant User `json:"new_chat_participant"`
|
||||
LeftChatParticipant User `json:"left_chat_participant"`
|
||||
NewChatTitle string `json:"new_chat_title"`
|
||||
NewChatPhoto string `json:"new_chat_photo"`
|
||||
NewChatPhoto []PhotoSize `json:"new_chat_photo"`
|
||||
DeleteChatPhoto bool `json:"delete_chat_photo"`
|
||||
GroupChatCreated bool `json:"group_chat_created"`
|
||||
}
|
||||
|
|
|
@ -13,13 +13,9 @@ func (bot *BotAPI) UpdatesChan(config UpdateConfig) error {
|
|||
for {
|
||||
updates, err := bot.GetUpdates(config)
|
||||
if err != nil {
|
||||
if bot.Debug {
|
||||
panic(err)
|
||||
} else {
|
||||
log.Println(err)
|
||||
log.Println("Failed to get updates, retrying in 3 seconds...")
|
||||
time.Sleep(time.Second * 3)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue