【问题标题】:Telegram Bot API Webhooks with Go, GoLang on HerokuTelegram Bot API Webhooks with Go, GoLang on Heroku
【发布时间】:2018-04-24 00:34:24
【问题描述】:

我使用 go-telegram-bot-api 构建 Telegram Bot 并将其部署在 Heroku 上。

我需要像以前在 Python 中那样设置 Webhooks,例如 in this Python case

在不提供证书文件的情况下,无法理解如何在go-telegram-bot-api 中设置 Webhooks。

主要示例包含这样的行:

如果您需要使用 webhook(如果您希望在 Google App Engine 上运行),您可以使用稍微不同的方法。

package main

import (
    "gopkg.in/telegram-bot-api.v4"
    "log"
    "net/http"
)

func main() {
    bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
    if err != nil {
        log.Fatal(err)
    }

    bot.Debug = true

    log.Printf("Authorized on account %s", bot.Self.UserName)

    _, err = bot.SetWebhook(tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, "cert.pem"))
    if err != nil {
        log.Fatal(err)
    }

    updates := bot.ListenForWebhook("/" + bot.Token)
    go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)

    for update := range updates {
        log.Printf("%+v\n", update)
    }
}

但是使用 Heroku 进行部署我如何在不提供 pem 证书文件的情况下收听 Webhooks?

【问题讨论】:

  • 我也在 Github 问题中向 go-telegram-bot-api 存储库提出了这个问题,并得到了一个很好的答案:您只需将其替换为 go http.ListenAndServe(":8080", nil),它似乎正在工作!

标签: heroku go webhooks telegram-bot telegram-webhook


【解决方案1】:

按照https://devcenter.heroku.com/articles/getting-started-with-go 获取入门代码。

initTelegram()webhookHandler() 是要研究的函数。

将代码部署到 Heroku 后,运行:

heroku logs --tail -a <YOUR-APP-NAME>

向机器人发送一些消息,您应该会看到记录的消息。

更新 1

检查您的应用 URL 是否与代码中的 baseURL 变量相同 -- 运行 heroku info -a <YOUR-APP-NAME> -- 您的 URL 应该与 Web URL 相同。

更新 2

为了检查您的 Telegram API Webhooks 响应,请在您的浏览器中 ping 此地址:https://api.telegram.org/bot<YOUR BOT TOKEN GOES HERE>/getWebhookInfo,您应该在该地址字符串中连接字符串 bot 和您的实际 Telegram Bot Token。

如果你不在 Heroku 上运行你的代码,根据Official Telegram API Reference,从终端运行curl 可能是一个选项:

$ curl -F "url=https://your.domain.or.ip.com" -F "certificate=@/etc/ssl/certs/bot.pem" https://api.telegram.org/bot<YOUR BOT TOKEN GOES HERE>/setWebhook

代码:

package main

import (
    "encoding/json"
    "io"
    "io/ioutil"
    "log"
    "os"

    "github.com/gin-gonic/gin"
    "gopkg.in/telegram-bot-api.v4"

    _ "github.com/heroku/x/hmetrics/onload"
    _ "github.com/lib/pq"
)

var (
    bot      *tgbotapi.BotAPI
    botToken = "<YOUR BOT TOKEN GOES HERE>"
    baseURL  = "https://<YOUR-APP-NAME>.herokuapp.com/"
)

func initTelegram() {
    var err error

    bot, err = tgbotapi.NewBotAPI(botToken)
    if err != nil {
        log.Println(err)
        return
    }

    // this perhaps should be conditional on GetWebhookInfo()
    // only set webhook if it is not set properly
    url := baseURL + bot.Token
    _, err = bot.SetWebhook(tgbotapi.NewWebhook(url))
    if err != nil {
        log.Println(err)
    } 
}

func webhookHandler(c *gin.Context) {
    defer c.Request.Body.Close()

    bytes, err := ioutil.ReadAll(c.Request.Body)
    if err != nil {
        log.Println(err)
        return
    }

    var update tgbotapi.Update
    err = json.Unmarshal(bytes, &update)
    if err != nil {
        log.Println(err)
        return
    }

    // to monitor changes run: heroku logs --tail
    log.Printf("From: %+v Text: %+v\n", update.Message.From, update.Message.Text)
}

func main() {
    port := os.Getenv("PORT")

    if port == "" {
        log.Fatal("$PORT must be set")
    }

    // gin router
    router := gin.New()
    router.Use(gin.Logger())

    // telegram
    initTelegram()
    router.POST("/" + bot.Token, webhookHandler)

    err := router.Run(":" + port)
    if err != nil {
        log.Println(err)
    }
}

祝你好运,玩得开心!

【讨论】:

  • 感谢您的想法。我已经实施了。但仍然是同样的问题。在 Heroku 上成功运行后没有任何反应。当我尝试使用 tu cURL 时,webhook 会得到这个 json - {"ok":true,"result":{"url":"https://sf-demo-bot.herokuapp.com/&lt;my_Telegram_Token&gt;","has_custom_certificate":false,"pending_update_count":30,"last_error_date":1510981838,"last_error_message":"Wrong response from the webhook: 404 Not Found","max_connections":40}}
  • 也许 Telegram API 无法得到 OK 响应?我尝试将c.String(200, "POST") 添加到webhookHandler 函数中,但没有再次发生。
  • 您是否尝试使用电报应用程序向您的机器人发送消息并观察 heroku 日志?我确信这是一个完整的解决方案。
  • 见上面的chat 本质上这是你的 URL 仔细检查你是否提供了正确的 heroku 应用 URL。
【解决方案2】:

如果您将 Heroku 用于您的机器人,则不需要证书。 Heroku 提供免费的 SSL 证书。因此,您将应用程序的 URL 放入 https 方案中,并在 heroku 为您的应用程序设置的 PORT 上使用 HTTP 服务器进行侦听。请参阅下面的示例以更好地理解。

func main() {
    // Create bot instance
    u := fetchUpdates(bot)

    go http.ListenAndServe(":" + PORT, nil)
}

func fetchUpdates(bot *tgbotapi.BotAPI) tgbotapi.UpdatesChannel {
    _, err = bot.SetWebhook(tgbotapi.NewWebhook("https://dry-hamlet-60060.herokuapp.com/instagram_profile_bot/" + bot.Token))
    if err != nil {
        fmt.Fatalln("Problem in setting Webhook", err.Error())
    }

    updates := bot.ListenForWebhook("/instagram_profile_bot/" + bot.Token)

    return updates
}

【讨论】:

  • 请您在 Heroku 应用地址的末尾澄清更多关于 /instagram_profile_bot/ 的信息?也许我的问题是我没有添加这个字符串?这个字符串的名字——这是 Go 编译的二进制文件的名字吗?还是什么?
  • @IlyaRusin Heroku 只允许应用运行一个 http 服务器。我的应用程序有几个用于其他目的的端点。 /instagram_profile_bot/ 是我希望我的机器人用于与 Telegram 服务器通信的端点。你可以换成/就可以了。
  • tbot.BotAPItbot.UpdateChan 是什么?是tgbotapi.BotAPI? 如果是的话-UpdateChan 是什么?我有undefined: tgbotapi.UpdateChan
  • tbot.BotAPItgbotapi.BotAPIUpdateChanUpdatesChannel ListenForWebhook 函数返回。
  • 我已经改变了所有这些东西,但我仍然无法听我的机器人。我认为图书馆有问题。我想我应该更仔细阅读https://core.telegram.org/bots/webhooks
猜你喜欢
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 2022-10-20
  • 1970-01-01
  • 2018-04-07
  • 2022-01-20
  • 2022-01-26
  • 2021-06-28
相关资源
最近更新 更多