- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Publish to telegram #15
Changes from 1 commit
d938e0f
908cda8
3ae8267
d8fb331
c741b89
ee439da
635a674
80ca198
be4eeb7
117ef40
bec8544
010a331
d3d0adb
b8312f0
69f08f9
2b98130
336fa15
c5a94a5
c2f5de1
727df45
395831a
ec63f0e
588a63f
e27a045
7193518
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
package proc | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
"time" | ||
|
@@ -26,7 +29,7 @@ func NewTelegramClient(token string) (*TelegramClient, error) { | |
|
||
bot, err := tb.NewBot(tb.Settings{ | ||
Token: token, | ||
Client: &http.Client{Timeout: 10 * time.Second}, | ||
Client: &http.Client{Timeout: 60 * 10 * time.Second}, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
|
@@ -48,18 +51,97 @@ func (client TelegramClient) Send(channelID string, item feed.Item) error { | |
return nil | ||
} | ||
|
||
contentLength, err := getContentLength(item.Enclosure.URL) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var message *tb.Message | ||
|
||
if contentLength < 50_000_000 { | ||
message, err = client.sendAudio(channelID, item) | ||
} else { | ||
message, err = client.sendText(channelID, item) | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] send telegram message: \n%s", message.Text) | ||
return err | ||
} | ||
|
||
func getContentLength(url string) (int64, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @umputun how mocking http response? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see httptest. You can run test server and provide whatever response you need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is an example of httptest.Server use in real life, from one of my projects https://github.com/go-pkgz/rest/blob/master/httperrors_test.go#L16 |
||
resp, err := http.Head(url) //nolint:gosec | ||
if err != nil { | ||
return 0, err | ||
} | ||
|
||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != 200 { | ||
return 0, errors.New("status code != 200") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably include the code in error will be useful |
||
} | ||
|
||
log.Printf("[DEBUG] Content-Length: %d, url: %s", resp.ContentLength, url) | ||
return resp.ContentLength, err | ||
} | ||
|
||
func (client TelegramClient) sendText(channelID string, item feed.Item) (*tb.Message, error) { | ||
message, err := client.Bot.Send( | ||
recipient{chatID: channelID}, | ||
client.getMessageHTML(item), | ||
tb.ModeHTML, | ||
tb.NoPreview, | ||
) | ||
|
||
return message, err | ||
} | ||
|
||
func (client TelegramClient) sendAudio(channelID string, item feed.Item) (*tb.Message, error) { | ||
file, err := client.downloadAudio(item.Enclosure.URL) | ||
if err != nil { | ||
return err | ||
return nil, err | ||
} | ||
|
||
log.Printf("[DEBUG] send telegram message: \n%s", message.Text) | ||
return err | ||
audio := tb.Audio{ | ||
File: tb.FromReader(bytes.NewReader(*file)), | ||
FileName: "1.mp3", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1.mp3 ? probably should be the file name from the feed? |
||
MIME: "audio/mpeg", | ||
Caption: client.getMessageHTML(item), | ||
Title: item.Title, | ||
} | ||
|
||
message, err := audio.Send( | ||
client.Bot, | ||
recipient{chatID: channelID}, | ||
&tb.SendOptions{ | ||
ParseMode: tb.ModeHTML, | ||
}, | ||
) | ||
|
||
return message, err | ||
} | ||
|
||
func (client TelegramClient) downloadAudio(url string) (*[]byte, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need in pointer return here, []byte is a slice backed by pointer already |
||
clientHTTP := &http.Client{Timeout: 60 * 10 * time.Second} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @umputun I set big timeout, it is OK ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hard-coded timeout is something to avoid. But I can add it to opts and pass in latter on |
||
|
||
resp, err := clientHTTP.Get(url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
log.Printf("[DEBUG] start download audio: %s", url) | ||
|
||
file, err := ioutil.ReadAll(resp.Body) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code reads file content to memory. For 50M file it is not too bad, but running multiple feeds at the same time can make it way too big. I don't even see why you need to read it to memory at all. Looks like all you need in your consumer is io.Reader, i.e. resp.Body can be passed to tb.FromReader directly |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Printf("[DEBUG] finish download audio: %s", url) | ||
return &file, err | ||
} | ||
|
||
// https://core.telegram.org/bots/api#html-style | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moving 50_000_000 to a const and naming it logically, like
maxTelegramFileSize
or smth like this will be nice