Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,124 @@ There are more examples on the [site](https://go-telegram-bot-api.dev/)
with detailed information on how to do many different kinds of things.
It's a great place to get started on using keyboards, commands, or other
kinds of reply markup.

If you need to use webhooks (if you wish to run on Google App Engine),
you may use a slightly different method.

```go
package main

import (
"log"
"net/http"

"github.com/go-telegram-bot-api/telegram-bot-api"
)

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)
}
info, err := bot.GetWebhookInfo()
if err != nil {
log.Fatal(err)
}
if info.LastErrorDate != 0 {
log.Printf("Telegram callback failed: %s", info.LastErrorMessage)
}
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)
}
}
```

If you need to publish your bot on AWS Lambda(or something like it) and AWS API Gateway,
you can use such example:

In this code used AWS Lambda Go net/http server adapter [algnhsa](https://github.com/akrylysov/algnhsa)

```go
package main

import (
"github.com/akrylysov/algnhsa"
"github.com/go-telegram-bot-api/telegram-bot-api"
"log"
"net/http"
)

func answer(w http.ResponseWriter, r *http.Request) {
bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
if err != nil {
log.Fatal(err)
}

bot.Debug = true
updates := bot.ListenForWebhookRespReqFormat(w, r)
for update := range updates {
if update.Message == nil {
continue
}
log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
msg.ReplyToMessageID = update.Message.MessageID
_, err := bot.Send(msg)
if err != nil {
log.Printf("Error send message: %s | Error: %s", msg.Text, err.Error())
}
}
}

func setWebhook(_ http.ResponseWriter, _ *http.Request) {
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.NewWebhook("https://your_api_gateway_address.com/"+bot.Token))
if err != nil {
log.Fatal(err)
}
info, err := bot.GetWebhookInfo()
if err != nil {
log.Fatal(err)
}
if info.LastErrorDate != 0 {
log.Printf("Telegram callback failed: %s", info.LastErrorMessage)
}
}

func main() {
http.HandleFunc("/set_webhook", setWebhook)
http.HandleFunc("/MyAwesomeBotToken", answer)
algnhsa.ListenAndServe(http.DefaultServeMux, nil)
}
```

If you need, you may generate a self signed certficate, as this requires
HTTPS / TLS. The above example tells Telegram that this is your
certificate and that it should be trusted, even though it is not
properly signed.

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3560 -subj "//O=Org\CN=Test" -nodes

Now that [Let's Encrypt](https://letsencrypt.org) is available,
you may wish to generate your free TLS certificate there.
22 changes: 22 additions & 0 deletions bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,33 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
}

ch <- *update
close(ch)
})

return ch
}

// ListenForWebhookRespReqFormat registers a http handler for a webhook.
func (bot *BotAPI) ListenForWebhookRespReqFormat(w http.ResponseWriter, r *http.Request) UpdatesChannel {
ch := make(chan Update, bot.Buffer)

func(w http.ResponseWriter, r *http.Request) {
update, err := bot.HandleUpdate(r)
if err != nil {
errMsg, _ := json.Marshal(map[string]string{"error": err.Error()})
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(errMsg)
return
}

ch <- *update
close(ch)
}(w, r)

return ch
}

// HandleUpdate parses and returns update received via webhook
func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
if r.Method != http.MethodPost {
Expand Down