package main import ( "errors" "fmt" tgbot "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/umputun/go-flags" "io/ioutil" "log" "net/http" "os" "strconv" "strings" "valera/commands" "valera/db" ) const ( version = "v1.2.0" ) type Opts struct { Token string `short:"t" long:"token" description:"Telegram api token"` Name string `short:"n" long:"name" description:"Telegram bot name" default:"@body_weight_loss_bot"` } var opts Opts func readToken() (string, error) { b, err := ioutil.ReadFile("token.txt") if err != nil { return "", err } str := string(b) return str, nil } func main() { run() } func run() { p := flags.NewParser(&opts, flags.PrintErrors|flags.PassDoubleDash|flags.HelpFlag) p.SubcommandsOptional = true if _, err := p.Parse(); err != nil { if err.(*flags.Error).Type != flags.ErrHelp { log.Println(errors.New("[ERROR] cli error: " + err.Error())) } os.Exit(2) } if opts.Token == "" { token, err := readToken() if err != nil { panic(err) } opts.Token = strings.ReplaceAll(token, "\n", "") } fmt.Println(opts.Token) bot, err := tgbot.NewBotAPI(opts.Token) if err != nil { panic(err) } u := tgbot.NewUpdate(0) u.Timeout = 60 updates, err := bot.GetUpdatesChan(u) if err != nil { panic(err) } go func() { http.HandleFunc("/go", func(w http.ResponseWriter, r *http.Request) { chats, err := db.GetAllChats() if err != nil { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) _, _ = fmt.Fprintf(w, `{"result":"error"}`) return } for _, chatID := range chats { sendGoToChat(bot, chatID) } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = fmt.Fprintf(w, `{"result":"ok"}`) }) http.HandleFunc("/stat", func(w http.ResponseWriter, r *http.Request) { chats, err := db.GetAllChats() if err != nil { fmt.Println(err) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) _, _ = fmt.Fprintf(w, `{"result":"error"}`) return } for _, chatID := range chats { if err := sendStatToChat(bot, chatID, "Напоминаю:\n- Cегодня больше не жрем!\n\n"); err != nil { fmt.Println(err) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) _, _ = fmt.Fprintf(w, `{"result":"error"}`) return } } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = fmt.Fprintf(w, `{"result":"ok"}`) }) port := ":10002" log.Println("Server is start up! port", port) log.Fatal(http.ListenAndServe(port, nil)) }() log.Println("Run", opts.Name) for update := range updates { if update.Message == nil { continue } text := update.Message.Text chatID := update.Message.Chat.ID username := update.Message.From.UserName userInfoDTO, err := db.GetChatInfo(chatID) if err != nil { log.Println(err) continue } switch userInfoDTO.GetStatus() { case db.UserStateGo: count, err := strconv.Atoi(text) if err != nil { log.Println(err) continue } if err := db.AddWorkout(chatID, db.NewWorkout("Отжимания", count, username)); err != nil { log.Println(err) continue } msgText := fmt.Sprintf("Отлично, %s, записал.", text) if count <= 0 { msgText = "Плохо, хочешь быть толстым и не красивым?" } msg := tgbot.NewMessage(chatID, msgText) msg.ReplyMarkup = tgbot.NewRemoveKeyboard(false) _, _ = bot.Send(msg) if err := db.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } continue case db.UserStateEat: count, err := strconv.Atoi(text) if err != nil { log.Println(err) continue } if err := db.AddCalories(chatID, db.NewCalories(count, username)); err != nil { log.Println(err) continue } if count <= 0 { _, _ = bot.Send(tgbot.NewMessage(chatID, "Все фигня, давай по новой")) continue } _, _ = bot.Send(tgbot.NewMessage(chatID, fmt.Sprintf("Калории, фу, %s, записал.", text))) if err := db.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } continue } command := commands.Command(strings.Replace(text, opts.Name, "", 1)) switch command { case commands.Start: _, _ = bot.Send(tgbot.NewMessage(chatID, fmt.Sprintf("Здорова, я Валера (%s), твой тренер (%d).", version, chatID))) if err := db.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } case commands.Help: _, _ = bot.Send(tgbot.NewMessage(chatID, "Вот что я умею:\n\n1) Предлагать размяться\n2) Показывать статистику\n3) Считать калории")) case commands.Ping: _, _ = bot.Send(tgbot.NewMessage(chatID, "pong")) case commands.Go: sendGoToChat(bot, chatID) case commands.Stat: if err := sendStatToChat(bot, chatID, ""); err != nil { fmt.Println(err) continue } case commands.Eat: if _, err := bot.Send(tgbot.NewMessage(chatID, "Вижу ты поел, отпишись сколько калорий было")); err == nil { if err := db.SetStatusToChat(chatID, db.UserStateEat); err != nil { log.Println(err) } } } } } func sendGoToChat(bot *tgbot.BotAPI, chatID int64) { msg := tgbot.NewMessage(chatID, "Давай немного разомнемся, отжимания, отпишись сколько раз ты выполнил упражнение") msg.ReplyMarkup = tgbot.NewReplyKeyboard( tgbot.NewKeyboardButtonRow( tgbot.NewKeyboardButton("1"), tgbot.NewKeyboardButton("2"), tgbot.NewKeyboardButton("3"), tgbot.NewKeyboardButton("5"), tgbot.NewKeyboardButton("8"), ), ) if _, err := bot.Send(msg); err == nil { if err := db.SetStatusToChat(chatID, db.UserStateGo); err != nil { log.Println(err) } } } func sendStatToChat(bot *tgbot.BotAPI, chatID int64, prefix string) error { stat, err := db.GetStat(chatID) if err != nil { return err } msgText := prefix + "Результаты за сегодня:\n" for k, v := range stat { msgText += fmt.Sprintf("- %s: %d\n", k, v) } _, _ = bot.Send(tgbot.NewMessage(chatID, msgText)) return nil }