Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Hamcha | 400e756356 | |
Hamcha | b27494aa52 |
|
@ -61,7 +61,7 @@ func (b *Broker) SendTextMessage(chat *APIChat, text string, extra *MessageOptio
|
|||
// SendPhoto sends a photo with an optional caption to a chat.
|
||||
// A reply_to message ID can be specified as optional parameter.
|
||||
func (b *Broker) SendPhoto(chat *APIChat, data []byte, filename string, caption string, extra *MessageOptions) {
|
||||
photodata := &ClientPhotoData{
|
||||
photodata := &ClientPhotoDataNet{
|
||||
ChatID: chat.ChatID,
|
||||
Filename: filename,
|
||||
Bytes: base64.StdEncoding.EncodeToString(data),
|
||||
|
|
|
@ -13,10 +13,10 @@ func executeClientCommand(action tg.ClientCommand, client net.Conn) {
|
|||
api.SendTextMessage(data)
|
||||
case tg.CmdGetFile:
|
||||
data := *(action.FileRequestData)
|
||||
api.GetFile(data, client, *action.Callback)
|
||||
api.GetFileNet(data, client, *action.Callback)
|
||||
case tg.CmdSendPhoto:
|
||||
data := *(action.PhotoData)
|
||||
api.SendPhoto(data)
|
||||
api.SendPhotoNet(data)
|
||||
case tg.CmdForwardMessage:
|
||||
data := *(action.ForwardMessageData)
|
||||
api.ForwardMessage(data)
|
||||
|
|
11
command.go
11
command.go
|
@ -68,6 +68,15 @@ type ClientTextMessageData struct {
|
|||
|
||||
// ClientPhotoData is the required data for a CmdSendPhoto request
|
||||
type ClientPhotoData struct {
|
||||
ChatID int64
|
||||
Bytes []byte
|
||||
Filename string
|
||||
Caption string `json:",omitempty"`
|
||||
ReplyID *int64 `json:",omitempty"`
|
||||
}
|
||||
|
||||
// ClientPhotoDataNet is the required data for a CmdSendPhoto request over the wire
|
||||
type ClientPhotoDataNet struct {
|
||||
ChatID int64
|
||||
Bytes string
|
||||
Filename string
|
||||
|
@ -156,7 +165,7 @@ type FileRequestData struct {
|
|||
type ClientCommand struct {
|
||||
Type ClientCommandType
|
||||
TextMessageData *ClientTextMessageData `json:",omitempty"`
|
||||
PhotoData *ClientPhotoData `json:",omitempty"`
|
||||
PhotoData *ClientPhotoDataNet `json:",omitempty"`
|
||||
ForwardMessageData *ClientForwardMessageData `json:",omitempty"`
|
||||
ChatActionData *ClientChatActionData `json:",omitempty"`
|
||||
InlineQueryResults *InlineQueryResponse `json:",omitempty"`
|
||||
|
|
74
telegram.go
74
telegram.go
|
@ -110,16 +110,24 @@ func (t Telegram) SendTextMessage(data ClientTextMessageData) (APIMessage, error
|
|||
return out.Result, err
|
||||
}
|
||||
|
||||
// SendPhoto sends a picture to a chat as a photo
|
||||
func (t Telegram) SendPhoto(data ClientPhotoData) (APIMessage, error) {
|
||||
// Decode photo from b64
|
||||
photolen := base64.StdEncoding.DecodedLen(len(data.Bytes))
|
||||
photobytes := make([]byte, photolen)
|
||||
decoded, err := base64.StdEncoding.Decode(photobytes, []byte(data.Bytes))
|
||||
if checkerr("SendPhoto/base64.Decode", err) {
|
||||
// SendPhotoNet decodes a network SendPhoto request and executes it
|
||||
func (t Telegram) SendPhotoNet(data ClientPhotoDataNet) (APIMessage, error) {
|
||||
byt, err := base64.StdEncoding.DecodeString(data.Bytes)
|
||||
if checkerr("SendPhotoNet/base64.Decode", err) {
|
||||
return APIMessage{}, err
|
||||
}
|
||||
|
||||
return t.SendPhoto(ClientPhotoData{
|
||||
ChatID: data.ChatID,
|
||||
Bytes: byt,
|
||||
Filename: data.Filename,
|
||||
Caption: data.Caption,
|
||||
ReplyID: data.ReplyID,
|
||||
})
|
||||
}
|
||||
|
||||
// SendPhoto sends a picture to a chat as a photo
|
||||
func (t Telegram) SendPhoto(data ClientPhotoData) (APIMessage, error) {
|
||||
// Write file into multipart buffer
|
||||
body := new(bytes.Buffer)
|
||||
writer := multipart.NewWriter(body)
|
||||
|
@ -127,7 +135,7 @@ func (t Telegram) SendPhoto(data ClientPhotoData) (APIMessage, error) {
|
|||
if checkerr("SendPhoto/multipart.CreateFormFile", err) {
|
||||
return APIMessage{}, err
|
||||
}
|
||||
part.Write(photobytes[0:decoded])
|
||||
part.Write(data.Bytes)
|
||||
|
||||
// Write other fields
|
||||
writer.WriteField("chat_id", strconv.FormatInt(data.ChatID, 10))
|
||||
|
@ -377,23 +385,13 @@ func (t Telegram) AnswerInlineQuery(data InlineQueryResponse) error {
|
|||
// GetFile sends a "getFile" API call to Telegram's servers and fetches the file
|
||||
// specified afterward. The file will be then send back to the client that requested it
|
||||
// with the specified callback id.
|
||||
func (t Telegram) GetFile(data FileRequestData, client net.Conn, callback int) {
|
||||
fail := func(msg string) {
|
||||
errmsg, _ := json.Marshal(BrokerUpdate{
|
||||
Type: BError,
|
||||
Error: &msg,
|
||||
Callback: &callback,
|
||||
})
|
||||
fmt.Fprintln(client, string(errmsg))
|
||||
}
|
||||
|
||||
func (t Telegram) GetFile(data FileRequestData) ([]byte, error) {
|
||||
postdata := url.Values{
|
||||
"file_id": {data.FileID},
|
||||
}
|
||||
resp, err := http.PostForm(t.apiURL("getFile"), postdata)
|
||||
if checkerr("GetFile/post", err) {
|
||||
fail("Server didn't like my request")
|
||||
return
|
||||
return nil, fmt.Errorf("Server didn't like my request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
@ -403,27 +401,23 @@ func (t Telegram) GetFile(data FileRequestData, client net.Conn, callback int) {
|
|||
}{}
|
||||
err = json.NewDecoder(resp.Body).Decode(&filespecs)
|
||||
if checkerr("GetFile/json.Decode", err) {
|
||||
fail("Server sent garbage (or error)")
|
||||
return
|
||||
return nil, fmt.Errorf("Server sent garbage (or error): %w", err)
|
||||
}
|
||||
if filespecs.Result == nil {
|
||||
fail("Server didn't send a file info, does the file exist?")
|
||||
return
|
||||
return nil, fmt.Errorf("Server didn't send a file info, does the file exist?")
|
||||
}
|
||||
result := *filespecs.Result
|
||||
|
||||
path := APIEndpoint + "file/bot" + t.Token + "/" + *result.Path
|
||||
fileresp, err := http.Get(path)
|
||||
if checkerr("GetFile/get", err) {
|
||||
fail("Could not retrieve file from Telegram's servers")
|
||||
return
|
||||
return nil, fmt.Errorf("Could not retrieve file from Telegram's servers: %w", err)
|
||||
}
|
||||
defer fileresp.Body.Close()
|
||||
|
||||
rawdata, err := ioutil.ReadAll(fileresp.Body)
|
||||
if checkerr("GetFile/ioutil.ReadAll", err) {
|
||||
fail("Could not read file data")
|
||||
return
|
||||
return nil, fmt.Errorf("Could not read file data: %w", err)
|
||||
}
|
||||
|
||||
rawlen := len(rawdata)
|
||||
|
@ -431,15 +425,35 @@ func (t Telegram) GetFile(data FileRequestData, client net.Conn, callback int) {
|
|||
// ???
|
||||
log.Printf("[GetFile] WARN ?? Downloaded file does not match provided filesize: %d != %d\n", rawlen, *result.Size)
|
||||
}
|
||||
b64data := base64.StdEncoding.EncodeToString(rawdata)
|
||||
return rawdata, nil
|
||||
}
|
||||
|
||||
func (t Telegram) GetFileNet(data FileRequestData, client net.Conn, callback int) {
|
||||
byt, err := t.GetFile(data)
|
||||
if err != nil {
|
||||
errstr := err.Error()
|
||||
errmsg, _ := json.Marshal(BrokerUpdate{
|
||||
Type: BError,
|
||||
Error: &errstr,
|
||||
Callback: &callback,
|
||||
})
|
||||
fmt.Fprintln(client, string(errmsg))
|
||||
}
|
||||
|
||||
b64data := base64.StdEncoding.EncodeToString(byt)
|
||||
clientmsg, err := json.Marshal(BrokerUpdate{
|
||||
Type: BFile,
|
||||
Bytes: &b64data,
|
||||
Callback: &callback,
|
||||
})
|
||||
if checkerr("GetFile/json.Marshal", err) {
|
||||
fail("Could not serialize reply JSON")
|
||||
errstr := "Could not serialize reply JSON"
|
||||
errmsg, _ := json.Marshal(BrokerUpdate{
|
||||
Type: BError,
|
||||
Error: &errstr,
|
||||
Callback: &callback,
|
||||
})
|
||||
fmt.Fprintln(client, string(errmsg))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue