package main import ( "context" "database/sql" "errors" "fmt" "log" "strconv" "github.com/go-telegram/bot" "github.com/go-telegram/bot/models" ) func KarmaChange(g Godette, change int) { log.Println("karma...") from := g.update.Message.From if g.update.Message.ReplyToMessage == nil { return } to := g.update.Message.ReplyToMessage.From if g.update.Message.ReplyToMessage.ForumTopicCreated != nil { return } // Sent karma to themself if from.ID == to.ID { text, err := GetRandomTemplateByTag("karma_self") if err != nil { text = "_Осуждаю самолайки_" } // b.SendMessage(ctx, &sendMessageParams) g.ReplyWithMarkdown(text) return } // Sent karma to me if me, err := g.GetMe(g.ctx); err == nil { if to.ID == me.ID { text, err := GetRandomTemplateByTag("karma_me") if err != nil { text = "_Спасибо, но мне это не нужно_" } g.ReplyWithMarkdown(text) return } } k := Karma{} if err := db.Get(&k, `SELECT * FROM karma WHERE from_user=$1 AND to_user=$2 AND strftime("%s", created) > strftime("%s", datetime("now"), "-1 minutes");`, from.ID, to.ID, change); err != nil { if errors.Is(err, sql.ErrNoRows) { log.Println("karma not found") _, insert_err := db.Exec(`INSERT INTO KARMA (from_user, to_user, change, message) VALUES ($1, $2, $3, $4)`, from.ID, to.ID, change, g.update.Message.Text) log.Println("Insert karma error:", insert_err) var from_karma, to_karma int db.Get(&from_karma, `SELECT total FROM total_karma WHERE id=$1`, from.ID) db.Get(&to_karma, `SELECT total FROM total_karma WHERE id=$1`, to.ID) tag_text := "raise" karma_text := "повысил" if change < 0 { tag_text = "lower" karma_text = "понизил" } default_karma_text := fmt.Sprintf( `*%[1]s \(%[3]d\)* %[5]s карму *%[2]s \(%[4]d\)*`, bot.EscapeMarkdown(from.FirstName), bot.EscapeMarkdown(to.FirstName), from_karma, to_karma, karma_text) text, err := GetRandomTemplateByTag(fmt.Sprintf("karma_%s", tag_text)) if err != nil { text = default_karma_text } g.ReplyWithMarkdown(text) return } log.Println(err) } else { text, err := GetRandomTemplateByTag("too_fast") if err != nil { text = "_Ты слишком шустрый, попробуй ещё раз позднее\\._" } g.ReplyWithMarkdown(text) } } func KarmaGoUp(ctx context.Context, b *bot.Bot, update *models.Update) { KarmaChange(Godette{b, ctx, update}, 1) } func KarmaGoDown(ctx context.Context, b *bot.Bot, update *models.Update) { KarmaChange(Godette{b, ctx, update}, -1) } func GetTopUsers(g Godette, reverse bool) { type User struct { Id int64 `db:"id"` Name string `db:"name"` Total int `db:"total"` } query := `SELECT * FROM total_karma ORDER BY TOTAL %s LIMIT 10;` descent := "DESC" header := "*Вот наш ТОП\\-10 пользователей:*\n\n" if reverse { descent = "" header = "*Вот наш _ОТРИЦАТЕЛЬНЫЙ_ ТОП\\-10:*\n\n" } query = fmt.Sprintf(query, descent) users := []User{} err := db.Select(&users, query) if err != nil { log.Println("can't top users:", err) } textResult := "" for i, user := range users { name := bot.EscapeMarkdown(user.Name) if user.Id == g.update.Message.From.ID { name = "_*" + name + "*_" } textResult += fmt.Sprintf("%d \\- %s \\(%s\\)\n", i, name, bot.EscapeMarkdown(strconv.Itoa(user.Total))) } _, send_err := g.Bot.SendMessage(g.ctx, &bot.SendMessageParams{ Text: fmt.Sprintf("%s%s", header, textResult), ParseMode: models.ParseModeMarkdown, ChatID: g.update.Message.Chat.ID, MessageThreadID: g.update.Message.MessageThreadID, }) if send_err != nil { log.Println("can't send top: ", send_err) } } func HandleUsersTop(g Godette) { GetTopUsers(g, false) } func HandleUsersBottom(g Godette) { GetTopUsers(g, true) } func HandleStats(g Godette) { user := g.update.Message.From userinfo := User{} var total_karma, karma_sent, karma_received, place int var same_karma []TotalKarma uerr := db.Get(&userinfo, `SELECT * FROM users WHERE id=$1;`, user.ID) if uerr != nil { g.ReplyWithText("Не могу найти пользователя") log.Println("can't find user info:", uerr) } db.Get(&total_karma, `SELECT total FROM total_karma WHERE id=$1;`, user.ID) db.Get(&karma_sent, `SELECT COUNT(*) FROM karma WHERE from_user=$1;`, user.ID) db.Get(&karma_received, `SELECT COUNT(*) FROM karma WHERE to_user=$1 AND from_user!=-1;`, user.ID) db.Get(&place, `SELECT COUNT(DISTINCT(total)) FROM total_karma WHERE total > $1`, total_karma) db.Select(&same_karma, `SELECT * FROM total_karma WHERE total = $1`, total_karma) same_karma_text := "" if len(same_karma) > 1 { same_karma_text += "\nПользователи с такой же кармой: " count := 0 for _, u := range same_karma { if u.Id == user.ID { continue } same_karma_text += bot.EscapeMarkdown(u.Name) count += 1 if count == 5 { same_karma_text += fmt.Sprintf(" \\(и ещё %d\\)", len(same_karma)-5) break } same_karma_text += ", " } } text := ` Вот что я знаю о тебе, *%[1]s*: Примерное количество сообщений: *%[5]d* Твоя карма: *%[2]s* Кармы отправил: *%[6]d* Кармы получил: *%[7]d* Примерное место среди пользователей: *%[3]d* %[4]s ` text_formatted := fmt.Sprintf( text, bot.EscapeMarkdown(user.FirstName), bot.EscapeMarkdown(strconv.Itoa(total_karma)), place+1, same_karma_text, userinfo.MessageCount, karma_sent+userinfo.KarmaSent, karma_received+userinfo.KarmaReceived, ) _, err := g.ReplyWithMarkdown(text_formatted) if err != nil { log.Println("can't send status:", err) fmt.Println(text_formatted) } } func HandleReactions(ctx context.Context, b *bot.Bot, u *models.Update) { reaction := u.MessageReaction had_like_before := false for _, r := range reaction.OldReaction { if r.Type == models.ReactionTypeTypeEmoji { switch r.ReactionTypeEmoji.Emoji { case "❤️", "👍": had_like_before = true } } } has_like_now := false for _, r := range reaction.NewReaction { if r.Type == models.ReactionTypeTypeEmoji { switch r.ReactionTypeEmoji.Emoji { case "🩷", "👍": has_like_now = true } } } if !had_like_before && has_like_now { log.Println("Now have like") } else if had_like_before && !has_like_now { log.Println("Have no likes") } else { log.Println("likes didn't changed") } }