NicoNex / echotron

An elegant and concurrent library for the Telegram bot API in Go.
https://t.me/s/echotronnews
GNU Lesser General Public License v3.0
363 stars 26 forks source link

How set webhook with custom certificate? #43

Closed vodves-vodves closed 3 months ago

vodves-vodves commented 9 months ago

How set webhook with custom certificate? It would be interesting to see an example

I've made a decision for myself I've edited the code a bit.

func (d *Dispatcher) ListenWebhookOptions(webhookURL string, dropPendingUpdates bool, opts *WebhookOptions) error {
    u, err := url.Parse(webhookURL)
    if err != nil {
        return err
    }

    whURL := fmt.Sprintf("%s%s", u.Hostname(), u.EscapedPath())
    if _, err = d.api.SetWebhook(whURL, dropPendingUpdates, opts); err != nil {
        return err
    }
    if d.httpServer != nil {
        mux := http.NewServeMux()
        mux.Handle("/", d.httpServer.Handler)
        mux.HandleFunc(u.EscapedPath(), d.HandleWebhook)
        d.httpServer.Handler = mux
        return d.httpServer.ListenAndServe()
    }
    http.HandleFunc(u.EscapedPath(), d.HandleWebhook)
    //edited from ListenAndServe to ListenAndServeTLS
    return http.ListenAndServeTLS(fmt.Sprintf(":%s", u.Port()), "cert.crt", "key.key", nil)
}

But this did not solve the problem, I have to manually send my certificate in a separate request in the browser, because the certificate does not want to be sent from the code.

Here's how the code loads the certificate, but doesn't send it

       //file name cert.crt
    certN := os.Getenv("CERT")
    file, err := os.Open(certN)
    if err != nil {
        log.Println(err)
        return
    }
    data, err := io.ReadAll(file)
    if err != nil {
        log.Println(err)
        return
    }
    cert := echotron.NewInputFileBytes(certN, data)
    opt := echotron.WebhookOptions{
        Certificate:    cert,
    }
    dsp := echotron.NewDispatcher(token, bot.NewBot)
    log.Println(dsp.ListenWebhookOptions(url, false, &opt))

Please test this and fix it)

NicoNex commented 9 months ago

Hi, thank you for the issue. I think that the reason why your code doesn't work is InputFile having private fields, this causes the query-builder to generate an empty json when creating the url query.

I'm investigating the situation further to try and come up with the best solution for this.

vodves-vodves commented 9 months ago

Also don't forget to look at this, because it didn't work without this change either

http.ListenAndServeTLS(fmt.Sprintf(":%s", u.Port()), "cert.crt", "key.key", nil)
NicoNex commented 9 months ago

Indeed I'm thinking of creating the following two methods:

func (d *Dispatcher) ListenWebhookTLS(webhookURL, certFile, keyFile string) error
func (d *Dispatcher) ListenWebhookOptionsTLS(webhookURL, certFile, keyFile string, dropPendingUpdates bool, opts *WebhookOptions) error
NicoNex commented 7 months ago

Hi, sorry for the very delayed answer. I've just pushed the version v3.30.0-alpha.1 with the aforementioned methods. Unfortunately I have no way to test if they work so it would be great if you could give me some feedback on it.