5

I want to use "telegram bot" with "echo framework" (When the server started, echo and telegram bot work together). I used the below code, but when I ran that, the telegram bot didn't start.

My main.go:

package main

import (
    "database/sql"
    "log"
    "net/http"
    "strings"

    tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
    "github.com/labstack/echo"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    _ = e.Start(":1323")

    db, err := sql.Open("sqlite3", "./criticism.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

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

    bot.Debug = true

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

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.Message == nil {
            continue
        }

        gp_msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Hi")
        bot.Send(gp_msg)
    }
}
MohammadReza
  • 427
  • 4
  • 16
  • This may not solve your problem, but I noticed that your are using the echo lib v1.x while the latest is v4. You probably want to add the version number you want to use to the echo import path. – chmike Dec 09 '19 at 11:45
  • The argument of `NewBotAPI` must be a valid telegram API token as per https://go-telegram-bot-api.github.io/getting-started/. You give an empty string. According to this documentation, the function will panic if the token is not valid. – chmike Dec 09 '19 at 11:56
  • @chmike He removed the token so he can post the code here. His problem is that it never reaches that part. – Navid Zarepak Dec 09 '19 at 12:49
  • @NavidZarepak The problem is thus not in telegram bot api. The OP doesn't say where and how the program fails. Error message ? Can't do much to help without this information. – chmike Dec 09 '19 at 13:00
  • @chmike You can. You can clearly see that the process doesn't reach any code after `_ = e.Start(":1323")`. And the problem: "the telegram bot didn't start.". Even if it can reach the codes (It won't), your argument about the token not being there is not going to solve anything because you know why it's not there and even if you don't, then you should ask. And if you can't help without any error messages, then ask for them so he can tell you that there is none which can help you to see the `_ = e.Start(":1323")` part and realize the actual problem. – Navid Zarepak Dec 09 '19 at 13:55
  • @chmike Also, according to the docs, if the token is invalid, the function will **NOT** panic but returns an error and you can handle it the way you want. – Navid Zarepak Dec 09 '19 at 13:59

1 Answers1

4

The problem is that when you start the echo server, then the code does not go any further.

In order to use both of them, you need to separate each of them into a different thread and also stop your program to finish and stop everything.

The simplest way is to separate the web server and telegram bot and start them separately:

func StartEcho() { 
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    _ = e.Start(":1323")
}

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

    bot.Debug = true

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

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.Message == nil {
            continue
        }

        gp_msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Hi")
        bot.Send(gp_msg)
    }
}

And then call them:

func main() {
    # Start the echo server in a separate thread
    go StartEcho()

    db, err := sql.Open("sqlite3", "./criticism.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    # Start the bot in a separate thread
    go StartBot()

    # To stop the program to finish and close
    select{}
    
    # You can also use https://golang.org/pkg/sync/#WaitGroup instead.
}

Or you can just run the last one in the main thread:

func main() {
    # Start the echo server in a separate thread
    go StartEcho()

    db, err := sql.Open("sqlite3", "./criticism.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    # Start the bot
    StartBot()
}

But if the last one stops, so will your entire program and the echo server with it. So you have to recover any panics and don't allow it to stop.

Navid Zarepak
  • 4,148
  • 1
  • 12
  • 26