This commit is contained in:
Владимир Фёдоров 2023-03-11 18:30:12 +07:00
parent 57755d28d2
commit 78aaa9b80a
4 changed files with 91 additions and 27 deletions

View File

@ -7,4 +7,5 @@ const (
Help = Command("/help") Help = Command("/help")
Ping = Command("/ping") Ping = Command("/ping")
Go = Command("/go") Go = Command("/go")
Stat = Command("/stat")
) )

View File

@ -4,6 +4,7 @@ type Config struct {
MongoURL string MongoURL string
DBName string DBName string
ChatsCollectionName string ChatsCollectionName string
WorkoutsCollectionName string
} }
func NewConfig() *Config { func NewConfig() *Config {
@ -11,5 +12,6 @@ func NewConfig() *Config {
MongoURL: "mongodb://mongo:o6bbyog3DHG0GYdu@158.160.11.219:27027", MongoURL: "mongodb://mongo:o6bbyog3DHG0GYdu@158.160.11.219:27027",
DBName: "valera", DBName: "valera",
ChatsCollectionName: "users", ChatsCollectionName: "users",
WorkoutsCollectionName: "workouts",
} }
} }

View File

@ -5,6 +5,7 @@ import (
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
"log"
"time" "time"
"valera/config" "valera/config"
) )
@ -23,7 +24,6 @@ type chatDTO struct {
type ChatInfoDTO struct { type ChatInfoDTO struct {
ChatID int64 `bson:"chat_id"` ChatID int64 `bson:"chat_id"`
Status string `bson:"status"` Status string `bson:"status"`
Workouts []Workout `bson:"workouts"`
} }
func (c *ChatInfoDTO) GetStatus() UserState { func (c *ChatInfoDTO) GetStatus() UserState {
@ -34,17 +34,22 @@ func (c *ChatInfoDTO) GetStatus() UserState {
} }
type Workout struct { type Workout struct {
ChatID int64 `bson:"chat_id"`
Name string `bson:"name"` Name string `bson:"name"`
Count int `bson:"count"` Count int `bson:"count"`
CreatedAt time.Time `bson:"created_at"`
Username string `bson:"username"`
} }
func NewWorkout( func NewWorkout(
name string, name string,
count int, count int,
username string,
) *Workout { ) *Workout {
return &Workout{ return &Workout{
Name: name, Name: name,
Count: count, Count: count,
Username: username,
} }
} }
@ -75,10 +80,13 @@ func AddChat(chatID int64) error {
return result.Err() return result.Err()
} }
func AddWorkoutInUser(chatID int64, workout *Workout) error { func AddWorkout(chatID int64, workout *Workout) error {
if err := AddChat(chatID); err != nil { if err := AddChat(chatID); err != nil {
return err return err
} }
workout.ChatID = chatID
loc, _ := time.LoadLocation("Asia/Novosibirsk")
workout.CreatedAt = time.Now().In(loc)
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() defer cancel()
@ -88,16 +96,18 @@ func AddWorkoutInUser(chatID int64, workout *Workout) error {
return err return err
} }
collection := client.Database(cfg.DBName).Collection(cfg.ChatsCollectionName) collection := client.Database(cfg.DBName).Collection(cfg.WorkoutsCollectionName)
_, err = collection.UpdateOne( _, err = collection.InsertOne(
ctx, ctx,
bson.M{"chat_id": chatID}, workout,
bson.M{"$push": bson.M{"workouts": workout}},
) )
return err return err
} }
func GetUserInfo(chatID int64) (*ChatInfoDTO, error) { func GetUserInfo(chatID int64) (*ChatInfoDTO, error) {
if err := AddChat(chatID); err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() defer cancel()
@ -131,3 +141,34 @@ func SetStatusInUser(chatID int64, status UserState) error {
) )
return err return err
} }
func GetStat(chatID int64) (map[string]int, error) {
if err := AddChat(chatID); err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL))
if err != nil {
return nil, err
}
collection := client.Database(cfg.DBName).Collection(cfg.WorkoutsCollectionName)
cursor, err := collection.Find(ctx, bson.M{"chat_id": chatID})
if err != nil {
return nil, err
}
res := map[string]int{}
for cursor.Next(context.Background()) {
var result Workout
if err := cursor.Decode(&result); err != nil {
log.Fatal(err)
}
res[result.Name] += result.Count
}
if err := cursor.Err(); err != nil {
log.Fatal(err)
}
return res, err
}

36
main.go
View File

@ -15,10 +15,9 @@ import (
) )
const ( const (
version = "v1.0.0" version = "v1.0.1"
) )
type Opts struct { type Opts struct {
Token string `short:"t" long:"token" description:"Telegram api token"` 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"` Name string `short:"n" long:"name" description:"Telegram bot name" default:"@body_weight_loss_bot"`
@ -81,8 +80,7 @@ func run() {
text := update.Message.Text text := update.Message.Text
chatID := update.Message.Chat.ID chatID := update.Message.Chat.ID
// username := update.Message.From.UserName username := update.Message.From.UserName
userInfoDTO, err := db.GetUserInfo(chatID) userInfoDTO, err := db.GetUserInfo(chatID)
if err != nil { if err != nil {
@ -92,15 +90,19 @@ func run() {
if userInfoDTO.GetStatus() == db.UserStateGo { if userInfoDTO.GetStatus() == db.UserStateGo {
count, err := strconv.Atoi(text) count, err := strconv.Atoi(text)
if err != nil { if err != nil {
log.Println(err)
continue continue
} }
if err := db.AddWorkoutInUser(chatID, db.NewWorkout("Отжимания", count)); err != nil { if err := db.AddWorkout(chatID, db.NewWorkout("Отжимания", count, username)); err != nil {
log.Println(err)
continue continue
} }
msg := tgbot.NewMessage(chatID, fmt.Sprintf("Отлично, %s, записал.", text)) msg := tgbot.NewMessage(chatID, fmt.Sprintf("Отлично, %s, записал.", text))
msg.ReplyMarkup = tgbot.NewHideKeyboard(false) msg.ReplyMarkup = tgbot.NewHideKeyboard(false)
_, _ = bot.Send(msg) _, _ = bot.Send(msg)
db.SetStatusInUser(chatID, db.UserStateNone) if err := db.SetStatusInUser(chatID, db.UserStateNone); err != nil {
log.Println(err)
}
continue continue
} }
@ -108,8 +110,11 @@ func run() {
switch command { switch command {
case commands.Start: case commands.Start:
_, _ = bot.Send(tgbot.NewMessage(chatID, fmt.Sprintf("Здорова, я Валера (%s), твой тренер (%d).", version, chatID))) _, _ = bot.Send(tgbot.NewMessage(chatID, fmt.Sprintf("Здорова, я Валера (%s), твой тренер (%d).", version, chatID)))
if err := db.SetStatusInUser(chatID, db.UserStateNone); err != nil {
log.Println(err)
}
case commands.Help: case commands.Help:
_, _ = bot.Send(tgbot.NewMessage(chatID, "Вот что я умею:\n\n1) Предлагать размяться")) _, _ = bot.Send(tgbot.NewMessage(chatID, "Вот что я умею:\n\n1) Предлагать размяться\n2) Показывать статистику"))
case commands.Ping: case commands.Ping:
_, _ = bot.Send(tgbot.NewMessage(chatID, "pong")) _, _ = bot.Send(tgbot.NewMessage(chatID, "pong"))
case commands.Go: case commands.Go:
@ -119,11 +124,26 @@ func run() {
tgbot.NewKeyboardButton("1"), tgbot.NewKeyboardButton("1"),
tgbot.NewKeyboardButton("2"), tgbot.NewKeyboardButton("2"),
tgbot.NewKeyboardButton("3"), tgbot.NewKeyboardButton("3"),
tgbot.NewKeyboardButton("5"),
tgbot.NewKeyboardButton("8"),
), ),
) )
if _, err = bot.Send(msg); err == nil { if _, err = bot.Send(msg); err == nil {
db.SetStatusInUser(chatID, db.UserStateGo) if err := db.SetStatusInUser(chatID, db.UserStateGo); err != nil {
log.Println(err)
} }
} }
case commands.Stat:
stat, err := db.GetStat(chatID)
if err != nil {
log.Println(err)
continue
}
msgText := "Результаты за сегодня:\n"
for k, v := range stat {
msgText += fmt.Sprintf("- %s: %d\n", k, v)
}
_, _ = bot.Send(tgbot.NewMessage(chatID, msgText))
}
} }
} }