diff --git a/.drone.yml b/.drone.yml index 5e9eae4..4e5685c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -30,6 +30,10 @@ steps: environment: TOKEN: from_secret: bot_token + MONGO_URL: + from_secret: mongo_url + DB_NAME: + from_secret: db_name PASSWORD: from_secret: ssh_pass settings: @@ -41,11 +45,13 @@ steps: from_secret: ssh_key port: from_secret: ssh_port - envs: [ TOKEN,PASSWORD ] + envs: [ TOKEN,MONGO_URL,DB_NAME,PASSWORD ] command_timeout: 10s script: - cd deploys/valera_tg_bot - echo $${TOKEN} > token.txt + - echo $${MONGO_URL} > mongo_url.txt + - echo $${DB_NAME} > "db_name.txt" - echo $${PASSWORD} | sudo -S systemctl restart valera trigger: diff --git a/.gitignore b/.gitignore index 2392583..00aea9a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,6 @@ go.work bin # bot -token.txt \ No newline at end of file +token.txt +mongo_url.txt +db_name.txt diff --git a/config/config.go b/config/config.go index 34426ec..586a70e 100644 --- a/config/config.go +++ b/config/config.go @@ -8,10 +8,10 @@ type Config struct { CaloriesCollectionName string } -func NewConfig() *Config { +func NewConfig(mongoURl string, dbName string) *Config { return &Config{ - MongoURL: "mongodb://mongo:o6bbyog3DHG0GYdu@158.160.11.219:27027", - DBName: "valera", + MongoURL: mongoURl, + DBName: dbName, ChatsCollectionName: "chats", WorkoutsCollectionName: "workouts", CaloriesCollectionName: "calories", diff --git a/db/calories.go b/db/calories.go new file mode 100644 index 0000000..aee7f08 --- /dev/null +++ b/db/calories.go @@ -0,0 +1,22 @@ +package db + +import "time" + +type Calories struct { + ChatID int64 `bson:"chat_id"` + Count int `bson:"count"` + CreatedAt time.Time `bson:"created_at"` + Username string `bson:"username"` +} + +func NewCalories( + count int, + username string, +) *Calories { + loc, _ := time.LoadLocation("Asia/Novosibirsk") + return &Calories{ + Count: count, + Username: username, + CreatedAt: time.Now().In(loc), + } +} diff --git a/db/chat.go b/db/chat.go new file mode 100644 index 0000000..73356f0 --- /dev/null +++ b/db/chat.go @@ -0,0 +1,22 @@ +package db + +const ( + UserStateNone = UserState("") + UserStateGo = UserState("Go") + UserStateEat = UserState("Eat") +) + +type UserState string + +type Chat struct { + ChatID int64 `bson:"chat_id"` +} + +type ChatInfo struct { + ChatID int64 `bson:"chat_id"` + Status string `bson:"status"` +} + +func (c *ChatInfo) GetStatus() UserState { + return UserState(c.Status) +} diff --git a/db/db.go b/db/db.go index b9429c4..87d3b37 100644 --- a/db/db.go +++ b/db/db.go @@ -10,88 +10,33 @@ import ( "valera/config" ) -const ( - UserStateNone = UserState("") - UserStateGo = UserState("Go") - UserStateEat = UserState("Eat") -) - -type UserState string - -type chatDTO struct { - ChatID int64 `bson:"chat_id"` +type DB struct { + cfg *config.Config } -type ChatInfoDTO struct { - ChatID int64 `bson:"chat_id"` - Status string `bson:"status"` -} - -func (c *ChatInfoDTO) GetStatus() UserState { - return UserState(c.Status) -} - -type Workout struct { - ChatID int64 `bson:"chat_id"` - Name string `bson:"name"` - Count int `bson:"count"` - CreatedAt time.Time `bson:"created_at"` - Username string `bson:"username"` -} - -func NewWorkout( - name string, - count int, - username string, -) *Workout { - loc, _ := time.LoadLocation("Asia/Novosibirsk") - return &Workout{ - Name: name, - Count: count, - Username: username, - CreatedAt: time.Now().In(loc), +func NewDB( + mongoURL string, + dbName string, +) *DB { + return &DB{ + cfg: config.NewConfig(mongoURL, dbName), } } -type Calories struct { - ChatID int64 `bson:"chat_id"` - Count int `bson:"count"` - CreatedAt time.Time `bson:"created_at"` - Username string `bson:"username"` -} - -func NewCalories( - count int, - username string, -) *Calories { - loc, _ := time.LoadLocation("Asia/Novosibirsk") - return &Calories{ - Count: count, - Username: username, - CreatedAt: time.Now().In(loc), - } -} - -var cfg *config.Config - -func init() { - cfg = config.NewConfig() -} - -func AddChat(chatID int64) error { +func (db *DB) AddChat(chatID int64) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return err } - collection := client.Database(cfg.DBName).Collection(cfg.ChatsCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.ChatsCollectionName) result := collection.FindOne(ctx, bson.M{"chat_id": chatID}) if result.Err() == mongo.ErrNoDocuments { - if _, err := collection.InsertOne(ctx, &chatDTO{ChatID: chatID}); err != nil { + if _, err := collection.InsertOne(ctx, &Chat{ChatID: chatID}); err != nil { return err } return nil @@ -99,11 +44,11 @@ func AddChat(chatID int64) error { return result.Err() } -func AddWorkout(chatID int64, workout *Workout) error { +func (db *DB) AddWorkout(chatID int64, workout *Workout) error { if workout.Count <= 0 { return nil } - if err := AddChat(chatID); err != nil { + if err := db.AddChat(chatID); err != nil { return err } workout.ChatID = chatID @@ -111,12 +56,12 @@ func AddWorkout(chatID int64, workout *Workout) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return err } - collection := client.Database(cfg.DBName).Collection(cfg.WorkoutsCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.WorkoutsCollectionName) _, err = collection.InsertOne( ctx, workout, @@ -124,11 +69,11 @@ func AddWorkout(chatID int64, workout *Workout) error { return err } -func AddCalories(chatID int64, calories *Calories) error { +func (db *DB) AddCalories(chatID int64, calories *Calories) error { if calories.Count <= 0 { return nil } - if err := AddChat(chatID); err != nil { + if err := db.AddChat(chatID); err != nil { return err } calories.ChatID = chatID @@ -136,12 +81,12 @@ func AddCalories(chatID int64, calories *Calories) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return err } - collection := client.Database(cfg.DBName).Collection(cfg.CaloriesCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.CaloriesCollectionName) _, err = collection.InsertOne( ctx, calories, @@ -149,36 +94,36 @@ func AddCalories(chatID int64, calories *Calories) error { return err } -func GetChatInfo(chatID int64) (*ChatInfoDTO, error) { - if err := AddChat(chatID); err != nil { +func (db *DB) GetChatInfo(chatID int64) (*ChatInfo, error) { + if err := db.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)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return nil, err } - collection := client.Database(cfg.DBName).Collection(cfg.ChatsCollectionName) - chatInfoDTO := &ChatInfoDTO{} + collection := client.Database(db.cfg.DBName).Collection(db.cfg.ChatsCollectionName) + chatInfoDTO := &ChatInfo{} if err := collection.FindOne(ctx, bson.M{"chat_id": chatID}).Decode(chatInfoDTO); err != nil { return nil, err } return chatInfoDTO, err } -func SetStatusToChat(chatID int64, status UserState) error { +func (db *DB) SetStatusToChat(chatID int64, status UserState) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return err } - collection := client.Database(cfg.DBName).Collection(cfg.ChatsCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.ChatsCollectionName) _, err = collection.UpdateOne( ctx, bson.M{"chat_id": chatID}, @@ -187,14 +132,14 @@ func SetStatusToChat(chatID int64, status UserState) error { return err } -func GetStat(chatID int64) (map[string]int, error) { - if err := AddChat(chatID); err != nil { +func (db *DB) GetStat(chatID int64) (map[string]int, error) { + if err := db.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)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return nil, err } @@ -204,7 +149,7 @@ func GetStat(chatID int64) (map[string]int, error) { res := map[string]int{} - collection := client.Database(cfg.DBName).Collection(cfg.WorkoutsCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.WorkoutsCollectionName) cursor, err := collection.Find( ctx, bson.M{ @@ -226,7 +171,7 @@ func GetStat(chatID int64) (map[string]int, error) { log.Fatal(err) } - caloriesCollection := client.Database(cfg.DBName).Collection(cfg.CaloriesCollectionName) + caloriesCollection := client.Database(db.cfg.DBName).Collection(db.cfg.CaloriesCollectionName) caloriesCursor, err := caloriesCollection.Find( ctx, bson.M{ @@ -251,23 +196,23 @@ func GetStat(chatID int64) (map[string]int, error) { return res, err } -func GetAllChats() ([]int64, error) { +func (db *DB) GetAllChats() ([]int64, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - client, err := mongo.Connect(ctx, options.Client().ApplyURI(cfg.MongoURL)) + client, err := mongo.Connect(ctx, options.Client().ApplyURI(db.cfg.MongoURL)) if err != nil { return nil, err } - collection := client.Database(cfg.DBName).Collection(cfg.ChatsCollectionName) + collection := client.Database(db.cfg.DBName).Collection(db.cfg.ChatsCollectionName) cursor, err := collection.Find(ctx, bson.M{}) if err != nil { return nil, err } var res []int64 for cursor.Next(context.Background()) { - var result ChatInfoDTO + var result ChatInfo if err := cursor.Decode(&result); err != nil { log.Fatal(err) } diff --git a/db/workout.go b/db/workout.go new file mode 100644 index 0000000..36d5149 --- /dev/null +++ b/db/workout.go @@ -0,0 +1,25 @@ +package db + +import "time" + +type Workout struct { + ChatID int64 `bson:"chat_id"` + Name string `bson:"name"` + Count int `bson:"count"` + CreatedAt time.Time `bson:"created_at"` + Username string `bson:"username"` +} + +func NewWorkout( + name string, + count int, + username string, +) *Workout { + loc, _ := time.LoadLocation("Asia/Novosibirsk") + return &Workout{ + Name: name, + Count: count, + Username: username, + CreatedAt: time.Now().In(loc), + } +} diff --git a/main.go b/main.go index 97a64c5..d3884ea 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ import ( ) const ( - version = "v1.2.0" + version = "v1.3.0" ) type Opts struct { @@ -26,8 +26,8 @@ type Opts struct { var opts Opts -func readToken() (string, error) { - b, err := ioutil.ReadFile("token.txt") +func readFile(filename string) (string, error) { + b, err := ioutil.ReadFile(filename) if err != nil { return "", err } @@ -50,7 +50,7 @@ func run() { } if opts.Token == "" { - token, err := readToken() + token, err := readFile("token.txt") if err != nil { panic(err) } @@ -63,6 +63,25 @@ func run() { 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 @@ -73,7 +92,7 @@ func run() { go func() { http.HandleFunc("/go", func(w http.ResponseWriter, r *http.Request) { - chats, err := db.GetAllChats() + chats, err := dataBase.GetAllChats() if err != nil { w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) @@ -81,7 +100,7 @@ func run() { return } for _, chatID := range chats { - sendGoToChat(bot, chatID) + sendGoToChat(bot, dataBase, chatID) } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -89,7 +108,7 @@ func run() { }) http.HandleFunc("/stat", func(w http.ResponseWriter, r *http.Request) { - chats, err := db.GetAllChats() + chats, err := dataBase.GetAllChats() if err != nil { fmt.Println(err) w.Header().Add("Content-Type", "application/json") @@ -98,7 +117,7 @@ func run() { return } for _, chatID := range chats { - if err := sendStatToChat(bot, chatID, "Напоминаю:\n- Cегодня больше не жрем!\n\n"); err != nil { + 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) @@ -128,7 +147,7 @@ func run() { chatID := update.Message.Chat.ID username := update.Message.From.UserName - userInfoDTO, err := db.GetChatInfo(chatID) + userInfoDTO, err := dataBase.GetChatInfo(chatID) if err != nil { log.Println(err) continue @@ -140,7 +159,7 @@ func run() { log.Println(err) continue } - if err := db.AddWorkout(chatID, db.NewWorkout("Отжимания", count, username)); err != nil { + if err := dataBase.AddWorkout(chatID, db.NewWorkout("Отжимания", count, username)); err != nil { log.Println(err) continue } @@ -151,7 +170,7 @@ func run() { msg := tgbot.NewMessage(chatID, msgText) msg.ReplyMarkup = tgbot.NewRemoveKeyboard(false) _, _ = bot.Send(msg) - if err := db.SetStatusToChat(chatID, db.UserStateNone); err != nil { + if err := dataBase.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } continue @@ -161,7 +180,7 @@ func run() { log.Println(err) continue } - if err := db.AddCalories(chatID, db.NewCalories(count, username)); err != nil { + if err := dataBase.AddCalories(chatID, db.NewCalories(count, username)); err != nil { log.Println(err) continue } @@ -170,7 +189,7 @@ func run() { continue } _, _ = bot.Send(tgbot.NewMessage(chatID, fmt.Sprintf("Калории, фу, %s, записал.", text))) - if err := db.SetStatusToChat(chatID, db.UserStateNone); err != nil { + if err := dataBase.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } continue @@ -180,7 +199,7 @@ func run() { 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 { + if err := dataBase.SetStatusToChat(chatID, db.UserStateNone); err != nil { log.Println(err) } case commands.Help: @@ -188,15 +207,15 @@ func run() { case commands.Ping: _, _ = bot.Send(tgbot.NewMessage(chatID, "pong")) case commands.Go: - sendGoToChat(bot, chatID) + sendGoToChat(bot, dataBase, chatID) case commands.Stat: - if err := sendStatToChat(bot, chatID, ""); err != nil { + 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 := db.SetStatusToChat(chatID, db.UserStateEat); err != nil { + if err := dataBase.SetStatusToChat(chatID, db.UserStateEat); err != nil { log.Println(err) } } @@ -204,7 +223,7 @@ func run() { } } -func sendGoToChat(bot *tgbot.BotAPI, chatID int64) { +func sendGoToChat(bot *tgbot.BotAPI, dataBase *db.DB, chatID int64) { msg := tgbot.NewMessage(chatID, "Давай немного разомнемся, отжимания, отпишись сколько раз ты выполнил упражнение") msg.ReplyMarkup = tgbot.NewReplyKeyboard( tgbot.NewKeyboardButtonRow( @@ -216,14 +235,14 @@ func sendGoToChat(bot *tgbot.BotAPI, chatID int64) { ), ) if _, err := bot.Send(msg); err == nil { - if err := db.SetStatusToChat(chatID, db.UserStateGo); err != nil { + if err := dataBase.SetStatusToChat(chatID, db.UserStateGo); err != nil { log.Println(err) } } } -func sendStatToChat(bot *tgbot.BotAPI, chatID int64, prefix string) error { - stat, err := db.GetStat(chatID) +func sendStatToChat(bot *tgbot.BotAPI, dataBase *db.DB, chatID int64, prefix string) error { + stat, err := dataBase.GetStat(chatID) if err != nil { return err }