Browse Source

Init

master
Andrey Kovalev 2 years ago
commit
b4dc5896e5
Signed by: Russia9
GPG Key ID: EC3AA65373CA51DC
  1. 4
      .dockerignore
  2. 4
      .gitignore
  3. 25
      .gitlab-ci.yml
  4. 19
      Dockerfile
  5. 13
      assets/layout.yml
  6. 2
      assets/locales/ru.yml
  7. 9
      bot/bot.go
  8. 27
      bot/handlers/add.go
  9. 105
      bot/handlers/code.go
  10. 92
      bot/handlers/delete.go
  11. 247
      bot/handlers/list.go
  12. 88
      bot/handlers/password.go
  13. 63
      bot/handlers/phone.go
  14. 27
      bot/handlers/router.go
  15. 25
      docker-compose.yml
  16. 57
      go.mod
  17. 429
      go.sum
  18. 130
      main.go
  19. 35
      storage/storage.go
  20. 54
      types/account.go
  21. 468
      userbot/bot.go
  22. 22
      userbot/eat.go
  23. 26
      userbot/motivation.go
  24. 22
      userbot/profile.go
  25. 23
      userbot/report.go
  26. 21
      utils/utils.go

4
.dockerignore

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
.idea/
*.iml
.env
data/

4
.gitignore vendored

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
.idea/
*.iml
.env
data/

25
.gitlab-ci.yml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
stages:
- build
services:
- docker:20.10.12-dind
variables:
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
build:
image: docker:20.10.12
stage: build
before_script:
# Login to GitLab Registry
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
# Pull last image to use cache
- docker pull "$TAG_LATEST" || true
script:
# Build Image
- docker build --cache-from "$TAG_LATEST" -t $TAG_COMMIT -t $TAG_LATEST .
# Push to GitLab Registry
- docker push $TAG_COMMIT
- docker push $TAG_LATEST

19
Dockerfile

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
FROM golang:1.18
# Set app workdir
WORKDIR /go/src/app
# Copy dependencies list
COPY go.mod go.sum ./
# Download dependencies
RUN go mod download
# Copy application sources
COPY . .
# Build app
RUN go build -o app .
# Run app
CMD ["./app"]

13
assets/layout.yml

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
settings:
token_env: TELEGRAM_TOKEN
parse_mode: html
locales_dir: assets/locales
buttons:
rules_accept:
unique: rules_accept
text: ✅ Принять
markups:
rules:
- [ rules_accept ]

2
assets/locales/ru.yml

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
rules: |
<b>⚠Внимание!</b> При использовании бота ваш <b>аккаунт в Telegram</b> и <b>игровой профиль</b> могут быть заблокированы в любой момент. Разработчик не несет ответственности за эти баны.

9
bot/bot.go

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
package bot
import (
"gopkg.in/tucnak/telebot.v3"
"gopkg.in/tucnak/telebot.v3/layout"
)
var Bot *telebot.Bot
var Layout *layout.Layout

27
bot/handlers/add.go

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
package handlers
import (
"context"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
)
func Add(ctx telebot.Context) error {
//return ctx.Send(bot.Layout.Text(ctx, "rules"), bot.Layout.Markup(ctx, "rules"))
err := storage.SetState(context.Background(), ctx.Sender().ID, "phone")
if err != nil {
return err
}
return ctx.Send("Введите <b>номер телефона</b>:")
}
func Accept(ctx telebot.Context) error {
err := storage.SetState(context.Background(), ctx.Sender().ID, "phone")
if err != nil {
return err
}
return ctx.Edit("Введите <b>номер телефона</b>:")
}

105
bot/handlers/code.go

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
package handlers
import (
"bytes"
"context"
"errors"
"github.com/gotd/td/session"
"github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/auth"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
"muskrat/types"
"muskrat/userbot"
"os"
"regexp"
"strconv"
"strings"
"time"
)
func Code(ctx telebot.Context, metadata []string) error {
if !regexp.MustCompile("^\\d \\d \\d \\d \\d$").MatchString(ctx.Text()) {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return ctx.Send("Неправильный формат кода. <b>Научись читать пж</b>")
}
sess := storage.Registration[ctx.Sender().ID]
if len(sess) == 0 {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return List(ctx)
}
s := session.StorageMemory{}
err := s.StoreSession(context.Background(), sess)
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return err
}
appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID"))
if err != nil {
return err
}
client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{
SessionStorage: &s,
})
err = client.Run(context.Background(), func(c context.Context) error {
_, err = client.Auth().SignIn(c, metadata[0], strings.ReplaceAll(ctx.Text(), " ", ""), metadata[1])
if errors.Is(err, auth.ErrPasswordAuthNeeded) {
b := new(bytes.Buffer)
err = s.Dump(b)
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return err
}
if len(storage.Registration) == 0 {
storage.Registration = make(map[int64][]byte)
}
storage.Registration[ctx.Sender().ID] = b.Bytes()
storage.SetState(context.Background(), ctx.Sender().ID, "password")
return ctx.Send("Введите <b>пароль 2fa</b>:")
} else if err != nil {
return err
}
self, err := client.Self(context.Background())
if err != nil {
return err
}
// Success
account := &types.Account{
ID: self.ID,
User: ctx.Sender().ID,
Session: storage.Registration[ctx.Sender().ID],
}
err = storage.DB.Create(account).Error
if err != nil {
return ctx.Send("Аккаунт с таким ID уже есть в боте")
}
if len(userbot.Userbots) == 0 {
userbot.Userbots = make(map[int64]*userbot.Userbot)
}
if userbot.Userbots[account.ID] != nil {
userbot.Userbots[account.ID].Stop()
delete(userbot.Userbots, account.ID)
}
ubot := &userbot.Userbot{
Account: account,
}
go ubot.Start(c)
userbot.Userbots[account.ID] = ubot
time.Sleep(time.Second * 2)
delete(storage.Registration, ctx.Sender().ID)
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return ctx.Send("Успешный логин" + self.FirstName + " " + self.LastName)
})
return err
}

92
bot/handlers/delete.go

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
package handlers
import (
"fmt"
"github.com/rs/zerolog/log"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
"muskrat/types"
"muskrat/userbot"
"strconv"
"strings"
)
func Delete(ctx telebot.Context) error {
accounts := make([]types.Account, 0)
storage.DB.Find(&accounts, "\"user\" = ?", strconv.FormatInt(ctx.Sender().ID, 10))
if len(accounts) == 0 {
return ctx.Send("Чтобы добавить аккаунт, /add")
}
markup := &telebot.ReplyMarkup{}
rows := make([]telebot.Row, 0)
for _, account := range accounts {
rows = append(rows, markup.Row(markup.Data(fmt.Sprintf("%s %s %d", account.Corp, account.Name, account.Level), "delete", strconv.FormatInt(account.ID, 10))))
}
markup.Inline(rows...)
return ctx.Send("Удалить аккаунт:", markup)
}
func AdminDelete(ctx telebot.Context) error {
if ctx.Sender().ID != 784726544 && ctx.Sender().ID != 709800052 {
return nil
}
params := strings.Split(ctx.Text(), " ")
if len(params) != 2 {
return ctx.Send("Неправильный формат")
}
id, err := strconv.ParseInt(params[1], 10, 64)
if err != nil {
return err
}
if userbot.Userbots[id].Account == nil {
return nil
}
account := userbot.Userbots[id].Account
err = userbot.Userbots[id].Stop()
if err != nil {
log.Warn().Err(err).Send()
}
delete(userbot.Userbots, id)
storage.DB.Unscoped().Delete(&account)
return ctx.Send("Успешно удалено")
}
func DeleteButton(ctx telebot.Context) error {
data := strings.Split(ctx.Data(), "|")
if len(data) != 1 {
return nil
}
id, err := strconv.ParseInt(data[0], 10, 64)
if err != nil {
return err
}
if userbot.Userbots[id].Account == nil {
return nil
}
account := userbot.Userbots[id].Account
err = userbot.Userbots[id].Stop()
if err != nil {
log.Warn().Err(err).Send()
}
delete(userbot.Userbots, id)
storage.DB.Unscoped().Delete(&account)
return ctx.Send("Успешно удалено")
}

247
bot/handlers/list.go

@ -0,0 +1,247 @@ @@ -0,0 +1,247 @@
package handlers
import (
"context"
"fmt"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
"muskrat/types"
"muskrat/userbot"
"muskrat/utils"
"regexp"
"strconv"
"strings"
)
func List(ctx telebot.Context) error {
accounts := make([]types.Account, 0)
storage.DB.Find(&accounts, "\"user\" = ?", strconv.FormatInt(ctx.Sender().ID, 10))
if len(accounts) == 0 {
return ctx.Send("Чтобы добавить аккаунт, /add")
}
markup := &telebot.ReplyMarkup{}
rows := make([]telebot.Row, 0)
for _, account := range accounts {
rows = append(rows, markup.Row(markup.Data(fmt.Sprintf("%s %s %d", account.Corp, account.Name, account.Level), "account", strconv.FormatInt(account.ID, 10))))
}
markup.Inline(rows...)
return ctx.Send("Список аккаунтов:", markup)
}
func Account(ctx telebot.Context) error {
if len(ctx.Data()) == 0 {
return ctx.Delete()
}
var account types.Account
storage.DB.First(&account, strings.Split(ctx.Data(), "|")[0])
markup := &telebot.ReplyMarkup{}
id := strconv.FormatInt(account.ID, 10)
markup.Inline(
markup.Row(
markup.Data(fmt.Sprintf("Еда: %s", utils.BoolEmoji(account.Eat)), "edit", id, "eat"),
markup.Data(fmt.Sprintf("Еда на 200: %s", utils.BoolEmoji(account.Eat200)), "edit", id, "eat_200"),
),
markup.Row(
markup.Data(fmt.Sprintf("Команда еды: %s", account.EatCommand), "edit", id, "eat_command"),
markup.Data(fmt.Sprintf("Шанс на еду: %d", account.EatChance), "edit", id, "eat_chance"),
),
markup.Row(
markup.Data(fmt.Sprintf("Лвлап: %s", utils.BoolEmoji(account.Levelup)), "edit", id, "levelup"),
markup.Data(fmt.Sprintf("Скилл: %s", utils.BoolLevelup(account.LevelupSkill)), "edit", id, "levelup_skill"),
),
markup.Row(
markup.Data(fmt.Sprintf("Пины: %s", utils.BoolEmoji(account.Pin)), "edit", id, "pin"),
markup.Data(fmt.Sprintf("Чат: %d", account.PinChat), "edit", id, "pin_chat"),
markup.Data(fmt.Sprintf("Пауза: %.1f", account.PinDelay), "edit", id, "pin_delay"),
markup.Data(fmt.Sprintf("Шанс: %d", account.PinChance), "edit", id, "pin_chance"),
),
markup.Row(
markup.Data(fmt.Sprintf("Репорты: %s", utils.BoolEmoji(account.Report)), "edit", id, "report"),
markup.Data(fmt.Sprintf("Чат: %d", account.ReportChat), "edit", id, "report_chat"),
markup.Data(fmt.Sprintf("Пауза: %.1f", account.ReportDelay), "edit", id, "report_delay"),
markup.Data(fmt.Sprintf("Шанс: %d", account.ReportChance), "edit", id, "report_chance"),
),
markup.Row(
markup.Data(fmt.Sprintf("Мобы: %s", utils.BoolEmoji(account.Mob)), "edit", id, "mob"),
markup.Data(fmt.Sprintf("Пауза: %.1f", account.MobDelay), "edit", id, "mob_delay"),
markup.Data(fmt.Sprintf("Шанс: %d", account.MobChance), "edit", id, "mob_chance"),
),
markup.Row(
markup.Data(fmt.Sprintf("Акула: %s", utils.BoolEmoji(account.Shark)), "edit", id, "shark"),
markup.Data(fmt.Sprintf("Пауза: %.1f", account.SharkDelay), "edit", id, "shark_delay"),
markup.Data(fmt.Sprintf("Команда: %s", utils.SharkEmoji(account.SharkTeam)), "edit", id, "shark_team"),
),
markup.Row(
markup.Data(fmt.Sprintf("Сон: %s", utils.BoolEmoji(account.Sleep)), "edit", id, "sleep"),
markup.Data(fmt.Sprintf("Сон в отеле? %s", utils.BoolEmoji(account.SleepHotel)), "edit", id, "sleep_hotel"),
),
markup.Row(
markup.Data(fmt.Sprintf("Слив моты: %s", utils.BoolEmoji(account.Motivation)), "edit", id, "motivation"),
markup.Data(fmt.Sprintf("Слив по кд: %s", utils.BoolEmoji(account.MotivationKD)), "edit", id, "motivation_kd"),
),
markup.Row(
markup.Data(fmt.Sprintf("Команда для слива: %s", account.MotivationCommand), "edit", id, "motivation_command"),
),
)
return ctx.EditOrSend(fmt.Sprintf("Аккаунт <b>%s %s</b>:", account.Corp, account.Name), markup)
}
func Edit(ctx telebot.Context) error {
data := strings.Split(ctx.Data(), "|")
if len(data) != 2 {
return nil
}
id, err := strconv.ParseInt(data[0], 10, 64)
if err != nil {
return err
}
if userbot.Userbots[id].Account == nil {
return nil
}
account := userbot.Userbots[id].Account
switch data[1] {
case "eat":
account.Eat = !account.Eat
case "eat_200":
account.Eat200 = !account.Eat200
case "levelup":
account.Levelup = !account.Levelup
case "levelup_skill":
account.LevelupSkill = !account.LevelupSkill
case "pin":
account.Pin = !account.Pin
case "report":
account.Report = !account.Report
case "mob":
account.Mob = !account.Mob
case "shark":
account.Shark = !account.Shark
case "shark_team":
account.SharkTeam = !account.SharkTeam
case "sleep":
account.Sleep = !account.Sleep
case "sleep_hotel":
account.SleepHotel = !account.SleepHotel
case "motivation":
account.Motivation = !account.Motivation
case "motivation_kd":
account.MotivationKD = !account.MotivationKD
default:
err = storage.SetState(context.Background(), ctx.Sender().ID, "edit", data...)
if err != nil {
return err
}
return ctx.Send(fmt.Sprintf("Введите значение <b>%s</b>:", data[1]))
}
userbot.Userbots[id].Account = account
storage.DB.Save(&account)
return Account(ctx)
}
func EditInput(ctx telebot.Context, data []string) error {
defer storage.ClearState(context.Background(), ctx.Sender().ID)
if len(data) != 2 {
return nil
}
id, err := strconv.ParseInt(data[0], 10, 64)
if err != nil {
return err
}
if userbot.Userbots[id] == nil {
return nil
}
account := userbot.Userbots[id].Account
switch data[1] {
case "eat_command":
if !regexp.MustCompile("/.*").MatchString(ctx.Text()) {
return ctx.Send("Неправильный формат")
}
account.EatCommand = ctx.Text()
case "eat_chance":
account.EatChance, err = strconv.Atoi(ctx.Text())
if err != nil {
return ctx.Send("Неправильный формат")
}
case "pin_chat":
account.PinChat, err = strconv.ParseInt(ctx.Text(), 10, 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "pin_delay":
account.PinDelay, err = strconv.ParseFloat(ctx.Text(), 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "pin_chance":
account.PinChance, err = strconv.Atoi(ctx.Text())
if err != nil {
return ctx.Send("Неправильный формат")
}
case "report_chat":
account.ReportChat, err = strconv.ParseInt(ctx.Text(), 10, 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "report_delay":
account.ReportDelay, err = strconv.ParseFloat(ctx.Text(), 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "report_chance":
account.ReportChance, err = strconv.Atoi(ctx.Text())
if err != nil {
return ctx.Send("Неправильный формат")
}
case "mob_delay":
account.MobDelay, err = strconv.ParseFloat(ctx.Text(), 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "mob_chance":
account.MobChance, err = strconv.Atoi(ctx.Text())
if err != nil {
return ctx.Send("Неправильный формат")
}
case "shark_delay":
account.SharkDelay, err = strconv.ParseFloat(ctx.Text(), 64)
if err != nil {
return ctx.Send("Неправильный формат")
}
case "motivation_command":
if !regexp.MustCompile("/.*").MatchString(ctx.Text()) {
return ctx.Send("Неправильный формат")
}
account.MotivationCommand = ctx.Text()
}
userbot.Userbots[id].Account = account
storage.DB.Save(&account)
return ctx.Send("Изменено")
}

88
bot/handlers/password.go

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
package handlers
import (
"context"
"github.com/gotd/td/session"
"github.com/gotd/td/telegram"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
"muskrat/types"
"muskrat/userbot"
"os"
"strconv"
"time"
)
func Password(ctx telebot.Context, metadata []string) error {
sess := storage.Registration[ctx.Sender().ID]
if len(sess) == 0 {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return List(ctx)
}
s := session.StorageMemory{}
err := s.StoreSession(context.Background(), sess)
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return err
}
appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID"))
if err != nil {
return err
}
client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{
SessionStorage: &s,
})
err = client.Run(context.Background(), func(c context.Context) error {
_, err = client.Auth().Password(context.Background(), ctx.Text())
if err != nil {
return err
}
// Success
self, err := client.Self(context.Background())
if err != nil {
return err
}
// Success
account := &types.Account{
ID: self.ID,
User: ctx.Sender().ID,
Session: storage.Registration[ctx.Sender().ID],
}
err = storage.DB.Create(account).Error
if err != nil {
return ctx.Send("Аккаунт с таким ID уже есть в боте")
}
if len(userbot.Userbots) == 0 {
userbot.Userbots = make(map[int64]*userbot.Userbot)
}
if userbot.Userbots[account.ID] != nil {
userbot.Userbots[account.ID].Stop()
delete(userbot.Userbots, account.ID)
}
ubot := &userbot.Userbot{
Account: account,
}
go ubot.Start(c)
userbot.Userbots[account.ID] = ubot
time.Sleep(time.Second * 2)
delete(storage.Registration, ctx.Sender().ID)
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return ctx.Send("Успешный логин" + self.FirstName + " " + self.LastName)
})
if err != nil {
delete(storage.Registration, ctx.Sender().ID)
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return ctx.Send("Неправильный пароль")
}
return err
}

63
bot/handlers/phone.go

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
package handlers
import (
"bytes"
"context"
"github.com/gotd/td/session"
"github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/auth"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
"os"
"regexp"
"strconv"
)
func Phone(ctx telebot.Context) error {
if !regexp.MustCompile("^[+]?[(]?[0-9]{3}[)]?[-\\s.]?[0-9]{3}[-\\s.]?[0-9]{4,8}$").MatchString(ctx.Text()) {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return List(ctx)
}
s := session.StorageMemory{}
appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID"))
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return err
}
client := telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{
SessionStorage: &s,
})
err = client.Run(context.Background(), func(c context.Context) error {
code, err := client.Auth().SendCode(c, ctx.Text(), auth.SendCodeOptions{})
if err != nil {
return err
}
err = storage.SetState(context.Background(), ctx.Sender().ID, "code", ctx.Text(), code.PhoneCodeHash)
if err != nil {
return err
}
return nil
})
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return List(ctx)
}
b := new(bytes.Buffer)
err = s.Dump(b)
if err != nil {
_ = storage.ClearState(context.Background(), ctx.Sender().ID)
return err
}
if len(storage.Registration) == 0 {
storage.Registration = make(map[int64][]byte)
}
storage.Registration[ctx.Sender().ID] = b.Bytes()
return ctx.Send("Введите <b>код</b> из личных сообщений в формате <code>1 2 3 4 5</code>:")
}

27
bot/handlers/router.go

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
package handlers
import (
"context"
"gopkg.in/tucnak/telebot.v3"
"muskrat/storage"
)
func Router(ctx telebot.Context) error {
state, metadata, err := storage.GetState(context.Background(), ctx.Sender().ID)
if err != nil {
return err
}
switch state {
case "phone":
return Phone(ctx)
case "code":
return Code(ctx, metadata)
case "password":
return Password(ctx, metadata)
case "edit":
return EditInput(ctx, metadata)
}
return List(ctx)
}

25
docker-compose.yml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
version: "3.3"
services:
redis:
image: redis:6.2.5
restart: always
ports:
- "127.0.0.1:6380:6379"
postgres:
image: postgres:14.1
restart: always
env_file: ".env"
ports:
- "127.0.0.1:5432:5432"
volumes:
- ./data:/var/lib/postgresql/data
muskrat:
build: .
restart: always
env_file: ".env"
depends_on:
- redis
- postgres

57
go.mod

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
module muskrat
go 1.18
require (
github.com/go-co-op/gocron v1.13.0
github.com/go-redis/redis/v8 v8.11.5
github.com/gotd/td v0.56.0
github.com/rs/zerolog v1.26.1
gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee
gorm.io/driver/postgres v1.3.4
gorm.io/gorm v1.23.4
)
require (
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/go-faster/errors v0.5.0 // indirect
github.com/go-faster/jx v0.34.0 // indirect
github.com/go-faster/xor v0.3.0 // indirect
github.com/goccy/go-yaml v1.9.5 // indirect
github.com/gotd/ige v0.2.2 // indirect
github.com/gotd/neo v0.1.5 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.11.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.2.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.10.0 // indirect
github.com/jackc/pgx/v4 v4.15.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/klauspost/compress v1.15.1 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/segmentio/asm v1.1.3 // indirect
github.com/spf13/cast v1.4.1 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
nhooyr.io/websocket v1.8.7 // indirect
rsc.io/qr v0.2.0 // indirect
)

429
go.sum

@ -0,0 +1,429 @@ @@ -0,0 +1,429 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-co-op/gocron v1.11.0 h1:ujOMubCpGcTxnnR/9vJIPIEpgwuAjbueAYqJRNr+nHg=
github.com/go-co-op/gocron v1.11.0/go.mod h1:qtlsoMpHlSdIZ3E/xuZzrrAbeX3u5JtPvWf2TcdutU0=
github.com/go-co-op/gocron v1.13.0 h1:BjkuNImPy5NuIPEifhWItFG7pYyr27cyjS6BN9w/D4c=
github.com/go-co-op/gocron v1.13.0/go.mod h1:GD5EIEly1YNW+LovFVx5dzbYVcIc8544K99D8UVRpGo=
github.com/go-faster/errors v0.5.0 h1:hS/zHFJ2Vb14jcupq5J9tk05XW+PFTmySOkDRByHBo4=
github.com/go-faster/errors v0.5.0/go.mod h1:/9SNBcg2ESJTYztBFEiM5Np6ns85BtPNMJd8lFTiFwk=
github.com/go-faster/jx v0.32.0 h1:AVAtgZ1FefKWMfD69DUIAQBV4ypXwHhFjh1ln9WAEEw=
github.com/go-faster/jx v0.32.0/go.mod h1:T561ezgn74siJgc+QzZzoGHokGBKxV6WZugVyfw+68c=
github.com/go-faster/jx v0.34.0 h1:4V/7G+v6S7MNRihCrMXqKgiZLLVs57Qv9HqAJ8zprtg=
github.com/go-faster/jx v0.34.0/go.mod h1:FdJhlaqQP+Drk7zHphPa6fF0Lg19rc6eh6dOugjpEFI=
github.com/go-faster/xor v0.3.0 h1:tc0bdVe31Wj999e5rEj7K3DhHyQNp2VydYyLFj3YSN8=
github.com/go-faster/xor v0.3.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-yaml v1.9.1/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
github.com/goccy/go-yaml v1.9.5 h1:Eh/+3uk9kLxG4koCX6lRMAPS1OaMSAi+FJcya0INdB0=
github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gotd/ige v0.2.2 h1:XQ9dJZwBfDnOGSTxKXBGP4gMud3Qku2ekScRjDWWfEk=
github.com/gotd/ige v0.2.2/go.mod h1:tuCRb+Y5Y3eNTo3ypIfNpQ4MFjrnONiL2jN2AKZXmb0=
github.com/gotd/neo v0.1.5 h1:oj0iQfMbGClP8xI59x7fE/uHoTJD7NZH9oV1WNuPukQ=
github.com/gotd/neo v0.1.5/go.mod h1:9A2a4bn9zL6FADufBdt7tZt+WMhvZoc5gWXihOPoiBQ=
github.com/gotd/td v0.55.2 h1:pxd4LgSnWODqRx1uQ79GgTjHMSRVnFO3YaKHWWSljF8=
github.com/gotd/td v0.55.2/go.mod h1:L3N+aEIojKkN7vjqnijFSMbwCSr+m5wpSyFZdxTCMA0=
github.com/gotd/td v0.56.0 h1:SlpVIxKbEhNzQ83lbkbBB0uS1QONCP+K1EE0YQOAHJU=
github.com/gotd/td v0.56.0/go.mod h1:wILjug50hgK8UkPwGcYRGQ6+7TYX5Uuf2yU873umgvM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8=
github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
github.com/jackc/pgconn v1.11.0 h1:HiHArx4yFbwl91X3qqIHtUFoiIfLNJXCQRsnzkiwwaQ=
github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns=
github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgtype v1.9.1 h1:MJc2s0MFS8C3ok1wQTdQxWuXQcB6+HwAm5x1CzW7mf0=
github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgtype v1.10.0 h1:ILnBWrRMSXGczYvmkYD6PsYyVFUNLTnIUJHHDLmqk38=
github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8=
github.com/jackc/pgx/v4 v4.14.1 h1:71oo1KAGI6mXhLiTMn6iDFcp3e7+zon/capWjl2OEFU=
github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M=
github.com/jackc/pgx/v4 v4.15.0 h1:B7dTkXsdILD3MF987WGGCcg+tvLW6bZJdEcqVFeU//w=
github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds=
github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.20.0 h1:N4oPlghZwYG55MlU6LXk/Zp00FVNE9X9wrYO8CEs4lc=
go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8=
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 h1:EN5+DfgmRMvRUrMGERW2gQl3Vc+Z7ZMnI/xdEpPSf0c=
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 h1:QyVthZKMsyaQwBTJE04jdNN0Pp5Fn9Qga0mrgxyERQM=
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee h1:0jS8G549Rie2L+BvXC+O+HPVyC+8gq3SpR/p2sJSfqg=
gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee/go.mod h1:1XHg/CpPZtstsm3WY57h1T4X/EQquwOgllQl/TjjgqI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To=
gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs=
gorm.io/driver/postgres v1.3.4 h1:evZ7plF+Bp+Lr1mO5NdPvd6M/N98XtwHixGB+y7fdEQ=
gorm.io/driver/postgres v1.3.4/go.mod h1:y0vEuInFKJtijuSGu9e5bs5hzzSzPK+LancpKpvbRBw=
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU=
gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg=
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=

130
main.go

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
package main
import (
"context"
"github.com/go-redis/redis/v8"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"gopkg.in/tucnak/telebot.v3"
"gopkg.in/tucnak/telebot.v3/layout"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"muskrat/bot"
"muskrat/bot/handlers"
"muskrat/storage"
"muskrat/types"
"muskrat/userbot"
"os"
"strconv"
"time"
)
func main() {
// Log settings
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
pretty, err := strconv.ParseBool(os.Getenv("LOG_PRETTY"))
if err != nil {
pretty = false
}
if pretty {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}
switch os.Getenv("LOG_LEVEL") {
case "DISABLED":
zerolog.SetGlobalLevel(zerolog.Disabled)
case "PANIC":
zerolog.SetGlobalLevel(zerolog.PanicLevel)
case "FATAL":
zerolog.SetGlobalLevel(zerolog.FatalLevel)
case "ERROR":
zerolog.SetGlobalLevel(zerolog.ErrorLevel)
case "WARN":
zerolog.SetGlobalLevel(zerolog.WarnLevel)
case "DEBUG":
zerolog.SetGlobalLevel(zerolog.DebugLevel)
case "TRACE":
zerolog.SetGlobalLevel(zerolog.TraceLevel)
default:
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
// Postgres
storage.DB, err = gorm.Open(postgres.Open(os.Getenv("POSTGRES_DSN")), &gorm.Config{})
if err != nil {
log.Fatal().Err(err).Send()
}
// Connection pools
db, err := storage.DB.DB()
if err != nil {
log.Fatal().Err(err).Send()
}
db.SetMaxIdleConns(10)
db.SetMaxOpenConns(100)
db.SetConnMaxLifetime(time.Hour)
err = storage.DB.AutoMigrate(&types.Account{})
if err != nil {
log.Fatal().Err(err).Send()
}
// Redis
redisURI, err := redis.ParseURL(os.Getenv("REDIS_URI"))
if err != nil {
log.Fatal().Str("module", "redis").Err(err).Send()
}
storage.Redis = redis.NewClient(redisURI)
defer storage.Redis.Close()
err = storage.Redis.Ping(context.TODO()).Err()
if err != nil {
log.Fatal().Str("module", "redis").Err(err).Send()
}
// Userbots
accounts := make([]types.Account, 0)
storage.DB.Find(&accounts)
userbot.Userbots = make(map[int64]*userbot.Userbot)
for _, account := range accounts {
current := account
userbot.Userbots[account.ID] = &userbot.Userbot{
Account: &current,
}
err = userbot.Userbots[account.ID].Start(context.Background())
if err != nil {
storage.DB.Unscoped().Delete(&current)
userbot.Userbots[account.ID].Stop()
delete(userbot.Userbots, account.ID)
}
}
// Layout
bot.Layout, err = layout.New("assets/layout.yml")
if err != nil {
log.Fatal().Str("module", "bot").Err(err).Send()
}
// Bot
bot.Bot, err = telebot.NewBot(bot.Layout.Settings())
if err != nil {
log.Fatal().Str("module", "bot").Err(err).Send()
}
// Middlewares
bot.Bot.Use(bot.Layout.Middleware("ru"))
// Handlers
bot.Bot.Handle("/add", handlers.Add)
bot.Bot.Handle("/delete", handlers.Delete)
bot.Bot.Handle("/adel", handlers.AdminDelete)
bot.Bot.Handle("\frules_accept", handlers.Accept)
bot.Bot.Handle("\faccount", handlers.Account)
bot.Bot.Handle("\fedit", handlers.Edit)
bot.Bot.Handle("\fdelete", handlers.DeleteButton)
bot.Bot.Handle(telebot.OnText, handlers.Router)
bot.Bot.Start()
}

35
storage/storage.go

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
package storage
import (
"context"
"github.com/go-redis/redis/v8"
"gorm.io/gorm"
"strconv"
"strings"
)
var DB *gorm.DB
var Redis *redis.Client
var Registration map[int64][]byte
func SetState(ctx context.Context, id int64, state string, metadata ...string) error {
for _, current := range metadata {
state += "|" + current
}
return Redis.Set(ctx, strconv.FormatInt(id, 10), state, 0).Err()
}
func GetState(ctx context.Context, id int64) (string, []string, error) {
cursor := Redis.Get(ctx, strconv.FormatInt(id, 10))
if cursor.Err() == redis.Nil {
return "", make([]string, 0), nil
} else if cursor.Err() != nil {
return "", nil, cursor.Err()
}
result := strings.Split(cursor.Val(), "|")
return result[0], result[1:], nil
}
func ClearState(ctx context.Context, id int64) error {
return Redis.Del(ctx, strconv.FormatInt(id, 10)).Err()
}

54
types/account.go

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
package types
import (
"gorm.io/gorm"
)
type Account struct {
ID int64 `json:"id"`
User int64 `json:"user"`
Session []byte `json:"session"`
Name string `json:"name"`
Corp string `json:"corp"`
Level int `json:"level"`
Eat bool `json:"eat"`
Eat200 bool `json:"eat_200"`
EatCommand string `json:"eat_command" gorm:"default:/eat"`
EatChance int `json:"eat_chance" gorm:"default:100"`
Levelup bool `json:"levelup"`
LevelupSkill bool `json:"levelup_skill"`
Pin bool `json:"pin"`
PinChat int64 `json:"pin_chat"`
PinDelay float64 `json:"pin_delay" gorm:"default:5"`
PinChance int `json:"pin_chance" gorm:"default:100"`
Report bool `json:"report"`
ReportChat int64 `json:"report_chat"`
ReportChatAccessHash int64 `json:"report_chat_access_hash"`
ReportDelay float64 `json:"report_delay" gorm:"default:5"`
ReportChance int `json:"report_chance" gorm:"default:100"`
Mob bool `json:"mob"`
MobDelay float64 `json:"mob_delay" gorm:"default:10"`
MobChance int `json:"mob_chance" gorm:"default:30"`
Sleep bool `json:"sleep"`
SleepHotel bool `json:"sleep_hotel" gorm:"default:true"`
Stock bool `json:"stock"`
StockCorp string `json:"stock_corp"`
Shark bool `json:"shark"`
SharkDelay float64 `json:"shark_delay" gorm:"default:1200"`
SharkTeam bool `json:"shark_team"`
Motivation bool `json:"motivation" gorm:"default:true"`
MotivationKD bool `json:"motivation_kd"`
MotivationCommand string `json:"motivation_command" gorm:"default:/harvest"`
gorm.Model
}

468
userbot/bot.go

@ -0,0 +1,468 @@ @@ -0,0 +1,468 @@
package userbot
import (
"context"
"fmt"
"github.com/go-co-op/gocron"
"github.com/gotd/td/session"
"github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/message"
"github.com/gotd/td/tg"
"github.com/rs/zerolog/log"
"math/rand"
"muskrat/storage"
"muskrat/types"
"os"
"regexp"
"strconv"
"strings"
"time"
)
type Userbot struct {
Account *types.Account
Client *telegram.Client
Sender *message.Sender
SW *message.RequestBuilder
Closed bool
Scheduler *gocron.Scheduler
}
var Userbots map[int64]*Userbot
func (b *Userbot) Start(ctx context.Context) error {
// Session
st := session.StorageMemory{}
err := st.StoreSession(ctx, b.Account.Session)
if err != nil {
return err
}
// Dispatcher
dp := tg.NewUpdateDispatcher()
dp.OnNewChannelMessage(func(c context.Context, e tg.Entities, u *tg.UpdateNewChannelMessage) error {
m, ok := u.Message.(*tg.Message)
if !ok {
return nil
}
from, ok := m.FromID.(*tg.PeerUser)
if !ok {
return nil
}
peer, ok := m.PeerID.(*tg.PeerChannel)
if !ok {
return nil
}
reportChatID := int64(0)
pinChatID := int64(0)
if len(strconv.FormatInt(b.Account.ReportChat, 10)) > 4 {
reportChatID, _ = strconv.ParseInt(strconv.FormatInt(b.Account.ReportChat, 10)[4:], 10, 64)
}
if len(strconv.FormatInt(b.Account.PinChat, 10)) > 4 {
pinChatID, _ = strconv.ParseInt(strconv.FormatInt(b.Account.PinChat, 10)[4:], 10, 64)
}
if (peer.ChannelID == b.Account.PinChat || peer.ChannelID == pinChatID) && b.Account.Pin && rand.Intn(100) <= b.Account.PinChance {
if from.UserID == 376592453 { // Pin
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*b.Account.PinDelay) * time.Minute)
r := regexp.MustCompile("(⚔В атаку на |🛡Все в защиту - )([^a-zA-Z]+)")
if !r.MatchString(m.Message) {
return nil
}
_, err = b.SW.Text(context.Background(), r.FindAllStringSubmatch(m.Message, -1)[0][2])
if err != nil {
fmt.Println(err)
}
markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup)
if !ok {
return nil
}
callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback)
if !ok {
return nil
}
_, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
Data: callback.Data,
})
if err != nil {
fmt.Println(err, "pin")
}
_, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{
Channel: &tg.InputChannelFromMessage{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
ChannelID: peer.ChannelID,
},
MaxID: m.ID,
})
if err != nil {
fmt.Println(err)
}
}
if from.UserID == 1714476897 || from.UserID == 1806724130 || from.UserID == 613165445 || from.UserID == 739073438 || from.UserID == 629902813 {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*b.Account.PinDelay) * time.Minute)
markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup)
if !ok {
return nil
}
callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback)
if !ok {
return nil
}
_, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
Data: callback.Data,
})
if err != nil {
fmt.Println(err)
}
_, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{
Channel: &tg.InputChannelFromMessage{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
ChannelID: peer.ChannelID,
},
MaxID: m.ID,
})
if err != nil {
fmt.Println(err)
}
}
}
if peer.ChannelID == 1109615116 { // Main Chat
if from.UserID == 376592453 { // Informator
if strings.HasPrefix(m.Message, "⚔В любом мире есть противники. 🐮Быки и 🐻Медведи") { // Shark
if b.Account.Shark {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*b.Account.SharkDelay+2) * time.Minute)
markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup)
if !ok {
return nil
}
button := 0
if b.Account.SharkTeam {
button = 1
}
callback, ok := markup.Rows[0].Buttons[button].(*tg.KeyboardButtonCallback)
if !ok {
return nil
}
_, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
Data: callback.Data,
})
if err != nil {
fmt.Println(err)
}
_, err = b.Client.API().ChannelsReadHistory(context.Background(), &tg.ChannelsReadHistoryRequest{
Channel: &tg.InputChannelFromMessage{
Peer: &tg.InputPeerChannel{ChannelID: peer.ChannelID, AccessHash: e.Channels[peer.ChannelID].AccessHash},
MsgID: m.ID,
ChannelID: peer.ChannelID,
},
MaxID: m.ID,
})
if err != nil {
fmt.Println(err)
}
}
}
}
}
if peer.ChannelID == b.Account.ReportChat || peer.ChannelID == reportChatID { // Update access hash
if b.Account.ReportChatAccessHash != e.Channels[peer.ChannelID].AccessHash {
b.Account.ReportChatAccessHash = e.Channels[peer.ChannelID].AccessHash
storage.DB.Save(b.Account)
}
}
return nil
})
dp.OnNewMessage(func(c context.Context, e tg.Entities, u *tg.UpdateNewMessage) error {
m, ok := u.Message.(*tg.Message)
if !ok {
return nil
}
peer, ok := m.PeerID.(*tg.PeerUser)
if !ok {
return nil
}
if peer.UserID == 227859379 { // StartupWarsBot
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*5+2) * time.Second)
if regexp.MustCompile("🎚(\\d+)").MatchString(m.Message) { // Update Profile
self, err := b.Client.Self(context.Background())
if err != nil {
return err
}
b.Account.Name = self.FirstName + " " + self.LastName
b.Account.Level, err = strconv.Atoi(regexp.MustCompile("🎚(\\d+)").FindAllStringSubmatch(m.Message, -1)[0][1])
b.Account.Corp = regexp.MustCompile("\\((.)[^)]+\\)").FindAllStringSubmatch(m.Message, -1)[0][1]
storage.DB.Save(b.Account)
}
if _, ok = m.Media.(*tg.MessageMediaDocument); (ok || strings.HasPrefix(m.Message, "Ты достиг нового уровня.")) && b.Account.Levelup { // Levelup
_, err = b.SW.Text(context.Background(), "/levelup")
if err != nil {
return err
}
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*5) * time.Second)
if b.Account.LevelupSkill {
_, err = b.SW.Text(context.Background(), "+1 🔨Практика")
if err != nil {
return err
}
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*5+5) * time.Second)
_, err = b.SW.Text(context.Background(), "+1 🐿Хитрость")
if err != nil {
return err
}
} else {
_, err = b.SW.Text(context.Background(), "+1 🎓Теория")
if err != nil {
return err
}
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*5+5) * time.Second)
_, err = b.SW.Text(context.Background(), "+1 🐢Мудрость")
if err != nil {
return err
}
}
}
if b.Account.Eat { // Eat
if regexp.MustCompile("🔋Выносливость на нуле").MatchString(m.Message) {
_, err = b.SW.Text(context.Background(), "/to_eat")
if err != nil {
return err
}
}
if regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").MatchString(m.Message) && !strings.HasPrefix(m.Message, "🍴Меню") {
data := regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").FindAllStringSubmatch(m.Message, -1)
if len(data[0]) >= 2 {
stamina, err := strconv.Atoi(data[0][1])
if err != nil {
return err
}
if b.Account.Eat200 {
if stamina < 200 {
_, err = b.SW.Text(context.Background(), "/to_eat")
if err != nil {
return err
}
}
} else {
if stamina < 100 {
_, err = b.SW.Text(context.Background(), "/to_eat")
if err != nil {
return err
}
}
}
}
}
if strings.HasPrefix(m.Message, "🍴Меню") {
data := regexp.MustCompile("🔋Выносливость: (\\d{1,3})%").FindAllStringSubmatch(m.Message, -1)
if len(data[0]) >= 2 {
stamina, err := strconv.Atoi(data[0][1])
if err != nil {
return err
}
if b.Account.Eat200 {
if stamina < 200 {
_, err = b.SW.Text(context.Background(), b.Account.EatCommand)
if err != nil {
return err
}
}
} else {
if stamina < 100 {
_, err = b.SW.Text(context.Background(), b.Account.EatCommand)
if err != nil {
return err
}
}
}
}
}
}
if strings.Contains(m.Message, "Твои результаты в битве") && b.Account.Report { // Forward Report
rand.Seed(time.Now().UnixNano())
_, err = b.Client.API().MessagesForwardMessages(context.Background(), &tg.MessagesForwardMessagesRequest{
FromPeer: &tg.InputPeerUser{UserID: 227859379},
ID: []int{m.ID},
ToPeer: &tg.InputPeerChannel{ChannelID: b.Account.ReportChat, AccessHash: b.Account.ReportChatAccessHash},
RandomID: []int64{rand.Int63()},
})
if err != nil {
return err
}
}
if strings.Contains(m.Message, "Опа, тебя начал грабить") && b.Account.Sleep {
markup, ok := m.ReplyMarkup.(*tg.ReplyInlineMarkup)
if !ok {
return nil
}
callback, ok := markup.Rows[0].Buttons[0].(*tg.KeyboardButtonCallback)
if !ok {
return nil
}
_, err = b.Client.API().MessagesGetBotCallbackAnswer(context.Background(), &tg.MessagesGetBotCallbackAnswerRequest{
Peer: &tg.InputPeerUser{UserID: peer.UserID, AccessHash: e.Users[peer.UserID].AccessHash},
MsgID: m.ID,
Data: callback.Data,
})
if err != nil {
return err
}
}
if strings.Contains(m.Message, b.Account.MotivationCommand) && b.Account.MotivationCommand != "" && b.Account.MotivationKD && b.Account.Motivation {
builder := b.Sender.Resolve("@StartupWarsBot")
if builder != nil {
_, err := builder.Text(context.Background(), b.Account.MotivationCommand)
if err != nil {
log.Error().Err(err)
}
}
}
// TODO: Sleep
// TODO: Mobs
}
return nil
})
// Telegram Client
appID, err := strconv.Atoi(os.Getenv("TELEGRAM_APP_ID"))
if err != nil {
return err
}
b.Client = telegram.NewClient(appID, os.Getenv("TELEGRAM_APP_HASH"), telegram.Options{
SessionStorage: &st,
UpdateHandler: &dp,
})
go func() {
err = b.Client.Run(context.Background(), func(c context.Context) error {
if err != nil {
return err
}
// Create Sender
b.Sender = message.NewSender(b.Client.API())
b.SW = b.Sender.Resolve("@StartupWarsBot")
if b.SW == nil {
fmt.Println("no startupwars")
return err
}
_, err = b.SW.Text(context.Background(), "/compact")
if err != nil {
return err
}
// Scheduler
location, err := time.LoadLocation("Europe/Moscow")
if err != nil {
return err
}
b.Scheduler = gocron.NewScheduler(location)
_, err = b.Scheduler.Every(30).Minutes().Do(MotivationTask(b))
if err != nil {
return err
}
_, err = b.Scheduler.Cron("45 9-21/3 * * *").Do(EatTask(b))
if err != nil {
return err
}
_, err = b.Scheduler.Cron("15 10-22/3 * * *").Do(EatTask(b))
if err != nil {
return err
}
_, err = b.Scheduler.Cron("1 10-22/3 * * *").Do(ReportTask(b))
if err != nil {
return err
}
_, err = b.Scheduler.Cron("0 1 * * *").Do(ProfileTask(b))
if err != nil {
return err
}
b.Scheduler.StartAsync()
for !b.Closed {
time.Sleep(time.Second)
}
return nil
})
if err != nil {
fmt.Println(err)
}
}()
return nil
}
func (b *Userbot) Stop() error {
b.Closed = true
if b.Scheduler != nil {
b.Scheduler.Stop()
}
return nil
}

22
userbot/eat.go

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
package userbot
import (
"context"
"github.com/rs/zerolog/log"
"math/rand"
"time"
)
func EatTask(b *Userbot) func() {
return func() {
rand.Seed(time.Now().UnixNano())
if b.Account.Eat && rand.Intn(100) <= b.Account.EatChance {
_, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/to_eat")
if err != nil {
log.Error().Err(err)
return
}
}
}
}

26
userbot/motivation.go

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
package userbot
import (
"context"
"github.com/rs/zerolog/log"
"math/rand"
"time"
)
func MotivationTask(b *Userbot) func() {
return func() {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*20) * time.Minute)
if b.Account.Motivation {
builder := b.Sender.Resolve("@StartupWarsBot")
if builder != nil {
_, err := builder.Text(context.Background(), b.Account.MotivationCommand)
if err != nil {
log.Error().Err(err)
return
}
}
}
}
}

22
userbot/profile.go

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
package userbot
import (
"context"
"github.com/rs/zerolog/log"
"math/rand"
"time"
)
func ProfileTask(b *Userbot) func() {
return func() {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*40) * time.Minute)
_, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/compact")
if err != nil {
log.Error().Err(err)
return
}
}
}

23
userbot/report.go

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
package userbot
import (
"context"
"github.com/rs/zerolog/log"
"math/rand"
"time"
)
func ReportTask(b *Userbot) func() {
return func() {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Float64()*b.Account.ReportDelay) * time.Minute)
if b.Account.Report && rand.Intn(100) <= b.Account.ReportChance {
_, err := b.Sender.Resolve("@StartupWarsBot").Text(context.Background(), "/battle")
if err != nil {
log.Error().Err(err)
return
}
}
}
}

21
utils/utils.go

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
package utils
func BoolEmoji(a bool) string {
if a {
return "✅"
}
return "🚫"
}
func SharkEmoji(a bool) string {
if a {
return "🐮"
}
return "🐻"
}
func BoolLevelup(a bool) string {
if a {
return "⚔"
}
return "🛡"
}
Loading…
Cancel
Save