Skip to content
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

Merged
merged 25 commits into from
Dec 6, 2019
Merged

Publish to telegram #15

merged 25 commits into from
Dec 6, 2019

Conversation

sgaynetdinov
Copy link
Contributor

@sgaynetdinov sgaynetdinov commented Nov 16, 2019

old PR #14

close #13

@sgaynetdinov sgaynetdinov marked this pull request as ready for review November 16, 2019 15:04
tg, err := proc.NewTelegramClient(opts.TG)
if err != nil {
log.Fatalf("[ERROR] failed initilization telegram client %s, %v", opts.TG, err)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when starting without TELEGRAM_TOKEN there will be an error,

  • is this the right behavior?
  • need to register this env in docker-compose?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not right, telegram support should be optional

Copy link
Owner

@umputun umputun Nov 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for "need to register this env in docker-compose?" - I think you are asking if it should be passed via docker-compose? Yes, if a user needs to set (or pass) TELEGRAM_TOKEN it has to be defined/declared in the compose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@sgaynetdinov sgaynetdinov requested a review from umputun November 18, 2019 16:08
@umputun
Copy link
Owner

umputun commented Nov 18, 2019

Looks good to me, I think I can merge it as-is, but first need to test it locally.

In the meantime, I would suggest 2 more changes (we can add it after the merge, up to you):

  1. Declare and use some Notifyer interface instead of direct TelegramClient in Processor. This will allow removing direct dependency and will help testing Processor without the actual telegram client involved.
  2. I'm not sure how timeouts handled here. None of telegram related methods seem to set timeout and none of them seems to use context for termination. We shouldn't hang indefinitely on failed connection to telegram but continue the normal operation after printing WARN level log message.

@umputun
Copy link
Owner

umputun commented Nov 18, 2019

I can't make it work. Created a new token, opened a new channel and all I get is "api error: Bad Request: chat not found". Btw, the message is not too helpful, knowing what chat is not found will be nice. In addition, it doesn't respect the lack of telegram_channel defined and trying to send on any feed.

It is also unclear to me if you expect me to set a channel with @ prefix or this library dealing with it.

@umputun
Copy link
Owner

umputun commented Nov 19, 2019

Ok, this one is running fine, I got a bunch of messages which is good. They also seem to be formatted nice, which is also good. However, none of them publishes mp3, they all links regardless of the size for mp3. From your earlier screenshots, I thought this is going to have media published if size allows (under 50m) but looks like it doesn't do it at all.

m3346-201911-19120142-51jlc

@sgaynetdinov
Copy link
Contributor Author

  1. I'm not sure how timeouts handled here. None of telegram related methods seem to set timeout and none of them seems to use context for termination. We shouldn't hang indefinitely on failed connection to telegram but continue the normal operation after printing WARN level log message.

Add timeouts 69f08f9

@sgaynetdinov
Copy link
Contributor Author

sgaynetdinov commented Nov 20, 2019

Ok, this one is running fine, I got a bunch of messages which is good. They also seem to be formatted nice, which is also good. However, none of them publishes mp3, they all links regardless of the size for mp3. From your earlier screenshots, I thought this is going to have media published if size allows (under 50m) but looks like it doesn't do it at all.

Early, I published in preview mode only one link and telegram published audio itself.
When the message consists of many links, not working as expected, shown the first link in a message (not audio).
Now I check the file size and attach it to the message (in process).

response := make(chan *responseTelegram)
go client.send(channelID, item, response)

select {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks wrong as it leaks goroutine on timeout. Timeout support has to be or on telegram's client level or on the level of http client injected to the telegram client.

Copy link
Owner

@umputun umputun Nov 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see https://github.com/tucnak/telebot/blob/v2/bot.go#L69 - you can pass http client and set timeout for the client, without any need in this dangerous workaround with goroutine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use http.Client 69f08f9

@sgaynetdinov
Copy link
Contributor Author

  1. In process of researching, I didn't find how to send in one message including text and audio. In documentation of Telegram I found Sending Messages in Bulk, but I don't know how to use it in package telebot.

  2. Bot can send at first text and after audio, but then messages shuffle (if messages more than two)

pic1

  1. It is possible to achieve result as on the screenshot only if this file will be not big.

pic3

@umputun
Copy link
Owner

umputun commented Nov 28, 2019

I'd suggest 3 for files under 50M and just a text (with a link to mp3) for bigger files

@sgaynetdinov
Copy link
Contributor Author

1

2

return err
}

func getContentLength(url string) (int64, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@umputun how mocking http response?

Copy link
Owner

Choose a reason for hiding this comment

The 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

Copy link
Owner

Choose a reason for hiding this comment

The 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

}

func (client TelegramClient) downloadAudio(url string) (*[]byte, error) {
clientHTTP := &http.Client{Timeout: 60 * 10 * time.Second}
Copy link
Contributor Author

@sgaynetdinov sgaynetdinov Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@umputun I set big timeout, it is OK ?

Copy link
Owner

Choose a reason for hiding this comment

The 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

return message, err
}

func (client TelegramClient) downloadAudio(url string) (*[]byte, error) {
Copy link
Owner

Choose a reason for hiding this comment

The 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

return err
audio := tb.Audio{
File: tb.FromReader(bytes.NewReader(*file)),
FileName: "1.mp3",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.mp3 ? probably should be the file name from the feed?

defer resp.Body.Close()

if resp.StatusCode != 200 {
return 0, errors.New("status code != 200")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably include the code in error will be useful


var message *tb.Message

if contentLength < 50_000_000 {
Copy link
Owner

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

app/proc/telegram_test.go Show resolved Hide resolved
app/proc/telegram_test.go Show resolved Hide resolved

log.Printf("[DEBUG] start download audio: %s", url)

file, err := ioutil.ReadAll(resp.Body)
Copy link
Owner

Choose a reason for hiding this comment

The 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

@umputun
Copy link
Owner

umputun commented Dec 6, 2019

I still see a few minor things, but generally, it seems to be ok and working. I'll merge it and we could address things after that.

@umputun umputun merged commit 5121af2 into umputun:master Dec 6, 2019
umputun added a commit that referenced this pull request Dec 6, 2019
@umputun
Copy link
Owner

umputun commented Dec 6, 2019

@sgaynetdinov thx for your work on PR. I have it merged and fixed a bunch of small things after the merge.

@sgaynetdinov
Copy link
Contributor Author

@umputun thanks for your review on my code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ability to publish to telegram
4 participants