Skip to content

Commit

Permalink
add /tags and /done commands
Browse files Browse the repository at this point in the history
  • Loading branch information
koenigskraut committed Aug 10, 2023
1 parent 8c453d6 commit 2ff0c6a
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 60 deletions.
4 changes: 3 additions & 1 deletion cmd/bot/handle_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ func handlePre() func(context.Context, tg.Entities, *tg.UpdateNewMessage, *cmd.H
case flags.RemoveTag:
return flags.Remove(ctx, m, user, answer)
case flags.AddTag:
return flags.Add(ctx, m, user, answer)
return flags.AddOne(ctx, m, user, answer)
case flags.AddTags:
return flags.AddMany(ctx, m, user, answer)
case flags.CheckTag:
return flags.Check(ctx, m, user, answer)
default:
Expand Down
2 changes: 2 additions & 0 deletions cmd/bot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ func run(ctx context.Context) error {
"start": cmd.Start,
"help": cmd.Help,
"cancel": cmd.Cancel,
"done": cmd.Done,
"tag": cmd.Tag,
"tags": cmd.Tags,
"remove": cmd.Remove,
"global": cmd.Global,
"check": cmd.Check,
Expand Down
11 changes: 11 additions & 0 deletions commands/done.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package commands

import (
"context"
"github.com/gotd/td/tg"
)

func Done(ctx context.Context, e tg.Entities, upd *tg.UpdateNewMessage, c *HelperCapture, _ string) error {
_, err := c.Sender.Answer(e, upd).Text(ctx, "Нечего завершать!")
return err
}
130 changes: 96 additions & 34 deletions commands/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,120 @@ package commands
import (
"context"
"errors"
"fmt"
"github.com/gotd/td/tg"
db "github.com/koenigskraut/piktagbot/database"
"github.com/koenigskraut/piktagbot/flags"
"github.com/koenigskraut/piktagbot/util"
"strings"
)

func Tag(ctx context.Context, e tg.Entities, upd *tg.UpdateNewMessage, c *HelperCapture, clear string) (err error) {
m, user := c.UserCapture.(*MessageSemaphore).MessageUserFromUpdate(upd)
answer := c.Sender.Answer(e, upd)
text := strings.TrimSpace(clear)
const (
errNoTag = iota
errNoSticker
errExists
successFlag
successRe
)

const (
errNoTagOne = "Вы не написали тег, который хотите прикрепить к стикеру!"
errNoTagMany = "Вы не написали тег, который хотите прикрепить к стикерам!"

errNoStickerOne = `В прикреплённом сообщении нет стикера, действие отменено%.s`
errNoStickerMany = `В прикреплённом сообщении нет стикера! Отправьте мне стикеры для тега "%s"`

errGeneral = "Что-то пошло не так, попробуйте ещё раз!"

// if there is no tag in a message return immediately
if text == "" {
_, err := answer.Text(ctx, "Вы не написали тег, который хотите прикрепить к стикеру!")
return err
errExistsOne = "У этого стикера уже есть этот тег, действие отменено"
errExistsMany = "У этого стикера уже есть этот тег, отправьте другие!"

successFlagOne = "Теперь отправьте мне стикер, к которому нужно прикрепить тег"
successFlagMany = "Теперь отправьте мне стикеры, к которым нужно прикрепить теги"

successReOne = "Тег добавлен!"
successReMany = "Тег добавлен! Пришлите мне следующий стикер или завершите действие командой /done"
)

type sm map[bool]string

func handleTag(isOne bool) CommandHandler {
chooseStr := map[uint8]map[bool]string{
errNoTag: sm{true: errNoTagOne, false: errNoTagMany},
errNoSticker: sm{true: errNoStickerOne, false: errNoStickerMany},
errExists: sm{true: errExistsOne, false: errExistsMany},
successFlag: sm{true: successFlagOne, false: successFlagMany},
successRe: sm{true: successReOne, false: successReMany},
}
flag := map[bool]int8{true: flags.AddTag, false: flags.AddTags}
return func(ctx context.Context, e tg.Entities, upd *tg.UpdateNewMessage, c *HelperCapture, clear string) (err error) {
m, user := c.UserCapture.(*MessageSemaphore).MessageUserFromUpdate(upd)
answer := c.Sender.Answer(e, upd)
text := strings.TrimSpace(clear)

// if there is no tag in a message return immediately
if text == "" {
_, err := answer.Text(ctx, chooseStr[errNoTag][isOne])
return err
}

// case 1: message is not a reply
// remember the tag and set a waiting-for-a-sticker flag
if m.ReplyTo == nil {
if err := user.SetFlag(flag[isOne], text); err != nil {
_, msgErr := answer.Text(ctx, errGeneral)
return errors.Join(err, msgErr)
}
_, err = answer.Text(ctx, chooseStr[successFlag][isOne])
return err
}

// case 1: message is a reply, handle re message
if m.ReplyTo != nil {
// case 2: message is a reply, handle re message
// many stickers wanted? set flag immediately
if !isOne {
if err := user.SetFlag(flag[isOne], text); err != nil {
_, msgErr := answer.Text(ctx, errGeneral)
return errors.Join(err, msgErr)
}
}
// get re message
mRep, _ := c.Client.MessagesGetMessages(
ctx,
[]tg.InputMessageClass{&tg.InputMessageReplyTo{ID: m.ID}},
)
// check if there is a sticker in it
media := mRep.(*tg.MessagesMessages).Messages[0].(*tg.Message).Media
if sticker, ok := util.StickerFromMedia(media); ok {
// if true, check if it has such a tag, add one if not
sTag := db.StickerTag{
User: user.UserID,
StickerID: sticker.ID,
Tag: text,
}
resp, _ := sTag.CheckAndAdd()
_, err := answer.Text(ctx, resp)
sticker, ok := util.StickerFromMedia(media)
// if false return
if !ok {
fmt.Println()
_, err := answer.Textf(
ctx,
chooseStr[errNoSticker][isOne],
text,
)
return err
}
_, err := answer.Textf(
ctx,
"В прикреплённом сообщении нет стикера! Отправьте мне стикер для тега \"%s\"",
text,
)
return err
}

// case 2: message is not a reply
// remember the tag and set a waiting-for-a-sticker flag
if err := user.SetFlag(flags.AddTag, text); err != nil {
_, msgErr := answer.Text(ctx, "Что-то пошло не так, попробуйте ещё раз!")
return errors.Join(err, msgErr)
// if true, check if sticker has such a tag, add one if not
sTag := db.StickerTag{
User: user.UserID,
StickerID: sticker.ID,
Tag: text,
}
err = sTag.CheckAndAdd()
var errTwo error
switch err {
case nil:
_, errTwo = answer.Text(ctx, chooseStr[successRe][isOne])
case db.StickerTagExists:
err = nil
_, errTwo = answer.Text(ctx, chooseStr[errExists][isOne])
default:
_, errTwo = answer.Text(ctx, errGeneral)
}
return errors.Join(err, errTwo)
}
_, err = answer.Text(ctx, "Теперь отправьте мне стикер, к которому нужно прикрепить тег")
return err
}

var Tag = handleTag(true)
var Tags = handleTag(false)
104 changes: 79 additions & 25 deletions flags/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,89 @@ import (
"strings"
)

func Add(ctx context.Context, m *tg.Message, u *database.User, answer *message.RequestBuilder) error {
if strings.HasPrefix(m.Message, "/cancel") {
u.Flag, u.FlagData = NoFlag, ""
if err := u.Save(); err != nil {
const (
finish = iota
errNoSticker
errExists
)

const (
finishCancel = "Действие отменено"
finishDone = "Действие завершено"

errNoStickerOne = "В сообщении нет стикера! Отправьте мне стикер для добавления тегов или отмените действие командой /cancel"
errNoStickerMany = "В сообщении нет стикера! Отправьте мне стикеры для добавления тегов или завершите действие командой /done"

errGeneral = "Что-то пошло не так, попробуйте ещё раз"

errExistsOne = "У этого стикера уже есть этот тег, действие отменено"
errExistsMany = "У этого стикера уже есть этот тег, отправьте другие!"

successOne = "Тег добавлен!"
successMany = "Тег добавлен! Пришлите мне следующий стикер или завершите действие командой /done"
)

type sm map[bool]string

func handleAdd(isOne bool) FlagHandler {
chooseStr := map[uint8]map[bool]string{
finish: sm{true: finishDone, false: finishCancel},
errNoSticker: sm{true: errNoStickerOne, false: errNoStickerMany},
errExists: sm{true: errExistsOne, false: errExistsMany},
}
//flag := map[bool]int8{true: flags.AddTag, false: flags.AddTags}
return func(ctx context.Context, m *tg.Message, u *database.User, answer *message.RequestBuilder) error {
done := strings.HasPrefix(m.Message, "/done")
cancel := strings.HasPrefix(m.Message, "/cancel")
if done || cancel {
u.Flag, u.FlagData = NoFlag, ""
if err := u.Save(); err != nil {
return err
}
_, err := answer.Text(ctx, chooseStr[finish][done])
return err
}
sticker, ok := util.StickerFromMedia(m.Media)
if !ok {
_, err := answer.Text(ctx, chooseStr[errNoSticker][isOne])
return err
}
// if there is a sticker, check if there is such a tag attached to it,
// if not — add one
sTag := database.StickerTag{
User: u.UserID,
StickerID: sticker.ID,
Tag: u.FlagData,
}
errDB := sTag.CheckAndAdd()
if errDB != nil {
if !errors.Is(errDB, database.StickerTagExists) {
_, errMsg := answer.Text(ctx, errGeneral)
return errors.Join(errDB, errMsg)
}
if isOne {
u.Flag, u.FlagData = NoFlag, ""
if err := u.Save(); err != nil {
_, errMsg := answer.Text(ctx, errGeneral)
return errors.Join(err, errMsg)
}
}
_, errMsg := answer.Text(ctx, chooseStr[errExists][isOne])
return errMsg
}
if !isOne {
_, err := answer.Text(ctx, successMany)
return err
}
_, err := answer.Text(ctx, "Действие отменено")
return err
}
sticker, ok := util.StickerFromMedia(m.Media)
if !ok {
_, err := answer.Text(ctx, "В сообщении нет стикера! Отправьте мне стикер для удаления тегов или "+
"отмените действие командой /cancel")
return err
}
// if there is a sticker, check if there is such a tag attached to it,
// if not — add one
sTag := database.StickerTag{
User: u.UserID,
StickerID: sticker.ID,
Tag: u.FlagData,
}
text, errDB := sTag.CheckAndAdd()
if errDB == nil {
u.Flag, u.FlagData = NoFlag, ""
if err := u.Save(); err != nil {
return err
_, errMsg := answer.Text(ctx, errGeneral)
return errors.Join(err, errMsg)
}
_, err := answer.Text(ctx, successOne)
return err
}
_, errMsg := answer.Text(ctx, text)
return errors.Join(errDB, errMsg)
}

var AddOne = handleAdd(true)
var AddMany = handleAdd(false)
10 changes: 10 additions & 0 deletions flags/base.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package flags

import (
"context"
"github.com/gotd/td/telegram/message"
"github.com/gotd/td/tg"
"github.com/koenigskraut/piktagbot/database"
)

const (
NoFlag = iota
RemoveTag
AddTag
AddTags
CheckTag
)

type FlagHandler func(ctx context.Context, m *tg.Message, u *database.User, answer *message.RequestBuilder) error

0 comments on commit 2ff0c6a

Please sign in to comment.