func (r *robot) Response(message tgbot.Message) tgbot.MessageConfig { if message.IsCommand() { r.SetCommand(message.Command(), message.CommandArguments()) } var response string switch r.currCommand { case Idle: response = r.responseIdle(message) case Read: response = r.responseRead(message) case Stats: response = r.responseStats(message) case Bookmark: response = r.responseBookmark(message) case Random: response = r.responseRandom(message) case Publish: response = r.responsePublish(message) } reply := tgbot.NewMessage(message.Chat.ID, response) reply.ReplyToMessageID = message.MessageID return reply }
// ---------------------------------------------------------------------------- func main() { commands, appConfig, err := getConfig() if err != nil { log.Fatal(err) } bot, err := tgbotapi.NewBotAPI(appConfig.token) if err != nil { log.Fatal(err) } log.Printf("Authorized on bot account: @%s", bot.Self.UserName) tgbotConfig := tgbotapi.NewUpdate(0) tgbotConfig.Timeout = appConfig.botTimeout botUpdatesChan, err := bot.GetUpdatesChan(tgbotConfig) if err != nil { log.Fatal(err) } users := NewUsers(appConfig) messageSignal := make(chan BotMessage, MESSAGES_QUEUE_SIZE) vacuumTicker := time.Tick(SECONDS_FOR_OLD_USERS_BEFORE_VACUUM * time.Second) saveToBDTicker := make(<-chan time.Time) exitSignal := make(chan struct{}) systemExitSignal := make(chan os.Signal) signal.Notify(systemExitSignal, os.Interrupt, os.Kill) if appConfig.persistentUsers { saveToBDTicker = time.Tick(SECONDS_FOR_AUTO_SAVE_USERS_TO_DB * time.Second) } var cacheTTL *cache.MemoryTTL if appConfig.cache > 0 { cacheTTL = cache.NewMemoryWithTTL(time.Duration(appConfig.cache) * time.Second) cacheTTL.StartGC(time.Duration(appConfig.cache) * time.Second * 2) } // all /shell2telegram sub-commands handlers internalCommands := map[string]func(Ctx) string{ "stat": cmdShell2telegramStat, "ban": cmdShell2telegramBan, "search": cmdShell2telegramSearch, "desc": cmdShell2telegramDesc, "rm": cmdShell2telegramRm, "exit": cmdShell2telegramExit, "version": cmdShell2telegramVersion, "broadcast_to_root": cmdShell2telegramBroadcastToRoot, "message_to_user": cmdShell2telegramMessageToUser, } doExit := false for !doExit { select { case telegramUpdate := <-botUpdatesChan: var messageCmd, messageArgs string allUserMessage := telegramUpdate.Message.Text if len(allUserMessage) > 0 && allUserMessage[0] == '/' { messageCmd, messageArgs = splitStringHalfBySpace(allUserMessage) } else { messageCmd, messageArgs = "/:plain_text", allUserMessage } allowPlainText := false if _, ok := commands["/:plain_text"]; ok { allowPlainText = true } replayMsg := "" if len(messageCmd) > 0 && (messageCmd != "/:plain_text" || allowPlainText) { users.AddNew(telegramUpdate.Message) userID := telegramUpdate.Message.From.ID allowExec := appConfig.allowAll || users.IsAuthorized(userID) ctx := Ctx{ appConfig: &appConfig, users: &users, commands: commands, userID: userID, allowExec: allowExec, messageCmd: messageCmd, messageArgs: messageArgs, messageSignal: messageSignal, chatID: telegramUpdate.Message.Chat.ID, exitSignal: exitSignal, cacheTTL: cacheTTL, } switch { // commands ................................. case messageCmd == "/auth" || messageCmd == "/authroot": replayMsg = cmdAuth(ctx) case messageCmd == "/help": replayMsg = cmdHelp(ctx) case messageCmd == "/shell2telegram" && users.IsRoot(userID): messageSubCmd, messageArgs := splitStringHalfBySpace(messageArgs) ctx.messageArgs = messageArgs if cmdHandler, ok := internalCommands[messageSubCmd]; ok { replayMsg = cmdHandler(ctx) } else { replayMsg = "Sub-command not found" } case allowExec && (allowPlainText && messageCmd == "/:plain_text" || messageCmd[0] == '/'): cmdUser(ctx) } // switch for commands if appConfig.logCommands { log.Printf("%s: %s", users.String(userID), allUserMessage) } sendMessage(messageSignal, telegramUpdate.Message.Chat.ID, []byte(replayMsg), false) } case botMessage := <-messageSignal: switch { case botMessage.messageType == msgIsText && !stringIsEmpty(botMessage.message): messageConfig := tgbotapi.NewMessage(botMessage.chatID, botMessage.message) if botMessage.isMarkdown { messageConfig.ParseMode = tgbotapi.ModeMarkdown } _, err = bot.Send(messageConfig) case botMessage.messageType == msgIsPhoto && len(botMessage.photo) > 0: bytesPhoto := tgbotapi.FileBytes{Name: botMessage.fileName, Bytes: botMessage.photo} _, err = bot.Send(tgbotapi.NewPhotoUpload(botMessage.chatID, bytesPhoto)) } if err != nil { log.Print("Bot send message error: ", err) } case <-saveToBDTicker: users.SaveToDB(appConfig.usersDB) case <-vacuumTicker: users.ClearOldUsers() case <-systemExitSignal: go func() { exitSignal <- struct{}{} }() case <-exitSignal: if appConfig.persistentUsers { users.needSaveDB = true users.SaveToDB(appConfig.usersDB) } doExit = true } } }