commit cd31f2d96bd2c57bbed53a3d0776c13ff9721021 Author: Кобелев Андрей Андреевич Date: Fri Jun 3 13:58:41 2022 +0300 init diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 0000000..d7403e1 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,2 @@ +[url "ssh://git.belvedersky.ru/"] + insteadOf = https://git.belvedersky.ru/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/bot.go b/bot.go new file mode 100644 index 0000000..f4c386a --- /dev/null +++ b/bot.go @@ -0,0 +1,91 @@ +package bot + +import ( + "fmt" + + "git.belvedersky.ru/common/logger/service" + "git.belvedersky.ru/common/tgbotapi" + "github.com/gofiber/fiber/v2" + "gopkg.in/telebot.v3" + "gopkg.in/telebot.v3/middleware" +) + +type ( + // Структура бота + Bot struct { + Config BotConfig // Конфиг + Bot *telebot.Bot // Бот + Api *tgbotapi.BotAPI // Апи + Log *service.LoggerService // Логгер + Msg chan<- telebot.Update // Сообщения + } + + // Настройки Бота + BotConfig struct { + Token string // Токен + UseWebhook bool // Использовать вебхук + UsePhone bool // Спрашивать телефон при авторизации в чатботе + Private bool // Отправлять сообщение только в приватный чат + Messages map[string]string // Сообщения + Handlers []string // Cписок хендлеров бота + } +) + +// Остановка бота +func (b *Bot) Stop() { + b.Log.Print(service.LogStruct{ + Message: fmt.Sprintf("Остановка чат бота https://t.me/%s", b.Bot.Me.Username), + }) + b.Bot.Stop() +} + +// Информация про бота +func (b *Bot) Self() *telebot.User { + return b.Bot.Me +} + +// Токен бота +func (b *Bot) Token() string { + return b.Bot.Token +} + +// Хендлер webhook +func (b *Bot) Handler(c *fiber.Ctx) error { + var update telebot.Update + b.Log.Log.Println(string(c.Body())) + if err := c.BodyParser(&update); err != nil { + return err + } + b.Msg <- update + return c.SendStatus(200) +} + +// Удаление сообщения +func (b *Bot) DeleteMessage(message *telebot.Message) error { + return b.Bot.Delete(message) +} + +// Отправка сообщения +func (b *Bot) SendMessage(chatId int64, message string, markup *telebot.ReplyMarkup) (m *telebot.Message, err error) { + chat, err := b.Bot.ChatByID(chatId) + if err != nil { + return nil, err + } + m, err = b.Bot.Send(chat, message, markup, telebot.ModeHTML) + return +} + +// Отправка файла +func (b *Bot) SendFile(chatId int64, file *telebot.Document, markup *telebot.ReplyMarkup) (m *telebot.Message, err error) { + chat, err := b.Bot.ChatByID(chatId) + if err != nil { + return nil, err + } + m, err = b.Bot.Send(chat, file, markup) + return +} + +func (b *Bot) RegisterMiddelwares() { + b.Bot.Use(middleware.Logger(b.Log.Log)) + b.Log.Print(service.LogStruct{Message: "registerMiddelwares"}) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dfcb060 --- /dev/null +++ b/go.mod @@ -0,0 +1,27 @@ +module git.belvedersky.ru/common/bots + +go 1.18 + +require github.com/puzpuzpuz/xsync v1.2.1 + +require ( + git.belvedersky.ru/common/db v0.1.0 // indirect + git.belvedersky.ru/common/logger v0.1.0 // indirect + git.belvedersky.ru/common/tgbotapi v0.6.0 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/gofiber/fiber/v2 v2.34.0 // indirect + github.com/jackc/pgx v3.6.2+incompatible // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/klauspost/compress v1.15.0 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.37.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect + golang.org/x/text v0.3.7 // indirect + gopkg.in/telebot.v3 v3.0.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..af9c375 --- /dev/null +++ b/go.sum @@ -0,0 +1,89 @@ +git.belvedersky.ru/common/db v0.1.0 h1:x8ZwiACI6LpBDuL+kFqY9a8K+Hp5X/UvavEf5NVnQ6E= +git.belvedersky.ru/common/db v0.1.0/go.mod h1:yCfe+fCJHU02M/RpH5HKQUBKWsCB0go/6NtV04SNJYg= +git.belvedersky.ru/common/logger v0.1.0 h1:69TkgeDWKIvi3l1CPmS64V9jGTDK/E0w9UI+UCbeNvQ= +git.belvedersky.ru/common/logger v0.1.0/go.mod h1:dR/XbwnltKoTPbp5Cr88EXDqeRgEnlZ5NvMzTbfvZJ4= +git.belvedersky.ru/common/tgbotapi v0.6.0 h1:meq8GNNKG8XADYXO1legSs4vLpBxzXXy2BHk5VSDB1U= +git.belvedersky.ru/common/tgbotapi v0.6.0/go.mod h1:UeXhGrHhZUA9PEwMgOkdCBDRW5e7EJkmUte/xMELiVI= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.10.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/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/gofiber/fiber/v2 v2.34.0 h1:96BJMw6uaxQhJsHY54SFGOtGgp9pgombK5Hbi4JSEQA= +github.com/gofiber/fiber/v2 v2.34.0/go.mod h1:ozRQfS+D7EL1+hMH+gutku0kfx1wLX4hAxDCtDzpj4U= +github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o= +github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= +github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +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.12/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/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/puzpuzpuz/xsync v1.2.1 h1:faRb6HT9XN3IAhnE7IP0TnPpokPK42qFKXkhQVkWNwM= +github.com/puzpuzpuz/xsync v1.2.1/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.37.0 h1:7WHCyI7EAkQMVmrfBhWTCOaeROb1aCBiTopx63LkMbE= +github.com/valyala/fasthttp v1.37.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +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.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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/telebot.v3 v3.0.0 h1:UgHIiE/RdjoDi6nf4xACM7PU3TqiPVV9vvTydCEnrTo= +gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/map.go b/map.go new file mode 100644 index 0000000..cf9eebc --- /dev/null +++ b/map.go @@ -0,0 +1,58 @@ +package bot + +import ( + "strconv" + + "git.belvedersky.ru/common/logger/service" + "github.com/gofiber/fiber/v2" + "github.com/puzpuzpuz/xsync" + "gopkg.in/telebot.v3" +) + +type Bots struct { + log *service.LoggerService // Логгер + I *xsync.MapOf[*Bot] +} + +func NewMap(Log *service.LoggerService) *Bots { + return &Bots{ + log: Log, + I: xsync.NewMapOf[*Bot](), + } +} + +func (b *Bots) Get(c *fiber.Ctx) error { + name := c.Params("name") + if name != "" { + b.log.Log.Println("Запрос на получение бота", name) + _b, ok := b.I.Load(name) + if !ok { + botId, err := strconv.Atoi(name) + if err != nil { + return err + } + b.I.Range(func(key string, bot *Bot) bool { + if bot.Self().ID == int64(botId) { + _b = bot + return false + } + return true + }) + if _b == nil { + return c.Status(404).SendString("not found") + } + } + return c.JSON(_b.Self()) + } + return c.Status(404).SendString("not found") +} + +func (b *Bots) GetAll(c *fiber.Ctx) error { + bots := []*telebot.User{} + b.I.Range(func(key string, value *Bot) bool { + bot := value + bots = append(bots, bot.Self()) + return true + }) + return c.JSON(bots) +} diff --git a/new.go b/new.go new file mode 100644 index 0000000..08fd0b0 --- /dev/null +++ b/new.go @@ -0,0 +1,83 @@ +package bot + +import ( + "fmt" + "time" + + "git.belvedersky.ru/common/db" + "git.belvedersky.ru/common/logger" + "git.belvedersky.ru/common/logger/service" + "git.belvedersky.ru/common/tgbotapi" + "gopkg.in/telebot.v3" +) + +// Cоздание бота +func new(url string, cfg BotConfig) (bot *telebot.Bot, err error) { + // client := &http.Client{Re} + bot, err = telebot.NewBot(telebot.Settings{URL: "https://api.telegram.org", Token: cfg.Token}) //Client: client}) + if err != nil { + return nil, err + } + if cfg.UseWebhook { + bot.Poller = &telebot.Webhook{ + MaxConnections: 100, + DropUpdates: true, + Endpoint: &telebot.WebhookEndpoint{ + PublicURL: fmt.Sprintf("%s/api/webhook/%s/%s", url, bot.Me.Username, cfg.Token), + }, + } + } else { + if err := bot.RemoveWebhook(true); err != nil { + return nil, err + } + bot.Poller = &telebot.LongPoller{Timeout: 10 * time.Second} + } + + if err != nil { + return nil, err + } + return bot, nil +} + +// Создание cервиса бота +func New(cfg BotConfig, lg *logger.Logger, db *db.PostgresRepository) (b *Bot, err error) { + + chatBot, err := new("https://test.belvedersky.ru", cfg) + if err != nil { + return nil, err + } + api, err := tgbotapi.NewBotAPI(cfg.Token) + if err != nil { + return nil, err + } + botLog := lg.Create(chatBot.Me.Username) + bot := Bot{ + Config: cfg, + Bot: chatBot, + Api: api, + Log: botLog, + Msg: chatBot.Updates, + } + return &bot, nil +} + +// Старт бота +func Start(b *Bot) (err error) { + + if b.Config.UseWebhook { + webhook, err := b.Bot.Webhook() + if err != nil { + return err + } + b.Log.Log.Println("Вебхук бота", webhook) + } + + defer func() { + if err := recover(); err != nil { + err = fmt.Errorf("%v", err) + } + }() + b.Log.Print(service.LogStruct{Message: "Бот " + b.Bot.Me.Username + " запущен"}) + b.Bot.Start() + return err +}