packages:
rename `errt` to `err_template`
rename `multe` to `flat_err`
rename `handler_structs` to `handler_params` with changes
logger:
move some fields to top logger
create sub logger when need
handler and sub-handler:
create sub params when need
plugin_utils:
rename `CustomSymbolCommand` to `FullCommand`
rename `SlashSymbolCommand` to `SlashCommand`
107 lines
3.3 KiB
Go
107 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"time"
|
|
|
|
"trbot/database"
|
|
"trbot/utils"
|
|
"trbot/utils/configs"
|
|
"trbot/utils/consts"
|
|
"trbot/utils/internal_plugin"
|
|
"trbot/utils/signals"
|
|
|
|
"github.com/go-telegram/bot"
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/pkgerrors"
|
|
)
|
|
|
|
func main() {
|
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
|
defer cancel()
|
|
|
|
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack // set stack trace func
|
|
logger := zerolog.New(zerolog.ConsoleWriter{Out: os.Stdout}).With().Timestamp().Logger()
|
|
ctx = logger.WithContext(ctx) // attach logger into ctx
|
|
|
|
// read bot configs
|
|
err := configs.InitBot(ctx)
|
|
if err != nil { logger.Fatal().Err(err).Msg("Failed to read bot configs") }
|
|
|
|
// writer log to a file or only display on console
|
|
if configs.IsUseMultiLogWriter(&logger) { ctx = logger.WithContext(ctx) } // re-attach logger into ctx
|
|
configs.CheckConfig(ctx) // check and auto fill some config
|
|
configs.ShowConst(ctx) // show build info
|
|
|
|
thebot, err := bot.New(configs.BotConfig.BotToken, []bot.Option{
|
|
bot.WithDefaultHandler(defaultHandler),
|
|
bot.WithAllowedUpdates(configs.BotConfig.AllowedUpdates),
|
|
}...)
|
|
if err != nil { logger.Fatal().Err(err).Msg("Failed to initialize bot") }
|
|
|
|
consts.BotMe, err = thebot.GetMe(ctx)
|
|
if err != nil { logger.Fatal().Err(err).Msg("Failed to get bot info") }
|
|
|
|
logger.Info().
|
|
Dict(utils.GetUserDict(consts.BotMe)).
|
|
Msg("Bot initialized")
|
|
|
|
database.InitAndListDatabases(ctx)
|
|
|
|
// set log level after bot initialized
|
|
zerolog.SetGlobalLevel(configs.BotConfig.LevelForZeroLog(false))
|
|
|
|
// start handler custom signals
|
|
go signals.SignalsHandler(ctx)
|
|
|
|
// register plugin (plugin use `init()` first, then plugin use `InitPlugins` second, and internal is the last)
|
|
internal_plugin.Register(ctx)
|
|
|
|
// Select mode by Webhook config
|
|
if configs.IsUsingWebhook(ctx) /* Webhook */ {
|
|
if configs.SetUpWebhook(ctx, thebot, &bot.SetWebhookParams{
|
|
URL: configs.BotConfig.WebhookURL,
|
|
AllowedUpdates: configs.BotConfig.AllowedUpdates,
|
|
}) {
|
|
logger.Info().
|
|
Str("listenAddress", consts.WebhookListenPort).
|
|
Msg("Working at Webhook Mode")
|
|
go thebot.StartWebhook(ctx)
|
|
err := http.ListenAndServe(consts.WebhookListenPort, thebot.WebhookHandler())
|
|
if err != nil {
|
|
logger.Fatal().
|
|
Err(err).
|
|
Msg("Webhook server failed")
|
|
}
|
|
} else {
|
|
logger.Fatal().
|
|
Str("webhookURL", configs.BotConfig.WebhookURL).
|
|
Msg("Failed to setup Webhook")
|
|
}
|
|
} else /* getUpdate, aka Long Polling */ {
|
|
// remove Webhook URL befor using getUpdate https://core.telegram.org/bots/api#getupdates
|
|
if configs.CleanRemoteWebhookURL(ctx, thebot) {
|
|
logger.Info().
|
|
Msg("Working at Long Polling Mode")
|
|
logger.Debug().
|
|
Msgf("visit https://api.telegram.org/bot%s/getWebhookInfo to check infos", configs.BotConfig.BotToken)
|
|
thebot.Start(ctx)
|
|
} else {
|
|
logger.Fatal().
|
|
Msg("Failed to remove Webhook URL")
|
|
}
|
|
}
|
|
|
|
// A loop wait for getUpdate mode, this program will exit in `utils\signals\signals.go`.
|
|
// This loop will only run when the exit signal is received in getUpdate mode.
|
|
// Webhook mode won't reach here, http.ListenAndServe() will keep program running until exit.
|
|
// They use the same code to exit, this loop is to give some time to save the database when receive exit signal.
|
|
for {
|
|
time.Sleep(5 * time.Second)
|
|
logger.Info().Msg("still waiting...")
|
|
}
|
|
}
|