valera/main.go

256 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.3.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 readFile(filename string) (string, error) {
b, err := ioutil.ReadFile(filename)
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 := readFile("token.txt")
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)
}
mongoURL, err := readFile("mongo_url.txt")
if err != nil {
panic(err)
}
mongoURL = strings.ReplaceAll(mongoURL, "\n", "")
fmt.Println(mongoURL)
dbName, err := readFile("db_name.txt")
if err != nil {
panic(err)
}
dbName = strings.ReplaceAll(dbName, "\n", "")
fmt.Println(dbName)
dataBase := db.NewDB(
mongoURL,
dbName,
)
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 := dataBase.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, dataBase, 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 := dataBase.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, dataBase, 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 := dataBase.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 := dataBase.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 := dataBase.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 := dataBase.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 := dataBase.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 := dataBase.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, dataBase, chatID)
case commands.Stat:
if err := sendStatToChat(bot, dataBase, chatID, ""); err != nil {
fmt.Println(err)
continue
}
case commands.Eat:
if _, err := bot.Send(tgbot.NewMessage(chatID, "Вижу ты поел, отпишись сколько калорий было")); err == nil {
if err := dataBase.SetStatusToChat(chatID, db.UserStateEat); err != nil {
log.Println(err)
}
}
}
}
}
func sendGoToChat(bot *tgbot.BotAPI, dataBase *db.DB, 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 := dataBase.SetStatusToChat(chatID, db.UserStateGo); err != nil {
log.Println(err)
}
}
}
func sendStatToChat(bot *tgbot.BotAPI, dataBase *db.DB, chatID int64, prefix string) error {
stat, err := dataBase.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
}