You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使Golang Echo框架与Telegram Bot协同运行?代码问题排查

问题分析与解决方案

你的Telegram Bot没启动的核心原因很明确:Echo的Start方法是阻塞式调用,当你执行_ = e.Start(":1323")后,程序会一直卡在这个方法里处理HTTP请求,后面初始化数据库、Bot的代码完全没机会运行,这就是Bot毫无反应的根源。

快速修复:用Goroutine启动Echo服务器

把Echo的启动逻辑放到goroutine中,让主线程能继续执行Bot的初始化和消息处理流程。修改后的完整代码如下:

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!")
	})

	// 用goroutine启动Echo,避免阻塞主线程
	go func() {
		if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Echo启动失败: %v", err)
		}
	}()

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

	// 务必替换成你的真实Telegram Bot Token!
	bot, err := tgbotapi.NewBotAPI("YOUR_BOT_TOKEN_HERE")
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = true
	log.Printf("已授权Bot账号: %s", bot.Self.UserName)

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

	updates, err := bot.GetUpdatesChan(u)
	if err != nil {
		log.Fatal(err)
	}

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

		gp_msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Hi")
		if _, err := bot.Send(gp_msg); err != nil {
			log.Printf("发送消息失败: %v", err)
		}
	}
}

关键修改说明:

  • 将e.Start放入匿名goroutine执行,主线程不会被阻塞,能顺利走到Bot初始化逻辑
  • 补充了Echo启动错误的处理,排除了优雅关闭时的http.ErrServerClosed错误
  • 增加了Bot消息发送的错误日志,避免悄悄忽略发送失败的情况
  • 特意标注了需要替换真实Bot Token(原代码里是空字符串,这本身也会导致Bot初始化失败)

进阶优化:优雅退出处理

如果需要支持优雅退出(比如收到Ctrl+C时,同时关闭Echo服务器和Bot更新通道),可以加上信号监听逻辑:

package main

import (
	"context"
	"database/sql"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	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!")
	})

	// 启动Echo服务器
	go func() {
		if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Echo启动失败: %v", err)
		}
	}()

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

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

	bot.Debug = true
	log.Printf("已授权Bot账号: %s", bot.Self.UserName)

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

	updates, err := bot.GetUpdatesChan(u)
	if err != nil {
		log.Fatal(err)
	}

	// 监听系统退出信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Println("开始关闭服务...")

	// 停止Bot接收更新
	bot.StopReceivingUpdates()

	// 优雅关闭Echo,设置5秒超时
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := e.Shutdown(ctx); err != nil {
		log.Fatalf("Echo强制关闭: %v", err)
	}

	log.Println("服务已退出")
}

这个方案会在收到中断信号时,先停止Bot的更新接收,再优雅关闭Echo服务器,避免强制退出导致的资源泄漏问题。

内容的提问来源于stack exchange,提问作者MohammadReza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:28