telegram messaging
parent
90bc515284
commit
19557e0bea
18
go.mod
18
go.mod
|
@ -3,27 +3,37 @@ module jannex/telegram-bot-manager
|
|||
go 1.21.0
|
||||
|
||||
require (
|
||||
git.ex.umbach.dev/Alex/roese-utils v1.0.16
|
||||
git.ex.umbach.dev/Alex/roese-utils v1.0.17
|
||||
github.com/gofiber/fiber/v2 v2.50.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
gorm.io/driver/mysql v1.5.2
|
||||
gorm.io/gorm v1.25.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.15.5 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rs/zerolog v1.31.0 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.50.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
gorm.io/driver/mysql v1.5.2 // indirect
|
||||
gorm.io/gorm v1.25.5 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
)
|
||||
|
|
40
go.sum
40
go.sum
|
@ -1,10 +1,27 @@
|
|||
git.ex.umbach.dev/Alex/roese-utils v1.0.16 h1:B9yVx5nL7FfUPJmqHDs58mq8MB2wSox1fK34EP3dqhc=
|
||||
git.ex.umbach.dev/Alex/roese-utils v1.0.16/go.mod h1:mov3ZaoSu+GBQU1uXN/AfSK6MF3/3WxUk38Tb6IKxbI=
|
||||
git.ex.umbach.dev/Alex/roese-utils v1.0.17 h1:uXq9/1sgIfu6qbyPPtgU0y0AbNFcS6IxXuNBcltEk/M=
|
||||
git.ex.umbach.dev/Alex/roese-utils v1.0.17/go.mod h1:mov3ZaoSu+GBQU1uXN/AfSK6MF3/3WxUk38Tb6IKxbI=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
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/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
|
||||
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw=
|
||||
github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw=
|
||||
|
@ -18,6 +35,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
|
@ -26,22 +45,43 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
|||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
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.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M=
|
||||
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
|
||||
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.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
|
||||
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
|
|
3
main.go
3
main.go
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"jannex/telegram-bot-manager/modules/config"
|
||||
"jannex/telegram-bot-manager/modules/database"
|
||||
"jannex/telegram-bot-manager/modules/telegram"
|
||||
"jannex/telegram-bot-manager/modules/utils"
|
||||
"jannex/telegram-bot-manager/routers/router"
|
||||
"os"
|
||||
|
@ -58,6 +59,8 @@ func main() {
|
|||
|
||||
router.SetupRoutes(app)
|
||||
|
||||
telegram.InitBot()
|
||||
|
||||
tblogger.AddSystemLog(rslogger.LogTypeInfo, "Server started")
|
||||
|
||||
app.Listen(config.Cfg.Host + ":" + config.Cfg.Port)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"jannex/telegram-bot-manager/modules/structs"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var tempVerifyCodes = make(map[string]structs.TempVerifyCode)
|
||||
var tMu sync.RWMutex
|
||||
|
||||
func AddTempVerifyCode(tempVerifyCode structs.TempVerifyCode) {
|
||||
tMu.Lock()
|
||||
defer tMu.Unlock()
|
||||
|
||||
tempVerifyCodes[tempVerifyCode.UserId] = tempVerifyCode
|
||||
}
|
||||
|
||||
func GetTempVerifyByCode(code string) (userId string, found bool) {
|
||||
tMu.RLock()
|
||||
defer tMu.RUnlock()
|
||||
|
||||
for _, v := range tempVerifyCodes {
|
||||
if v.Code == code {
|
||||
return v.UserId, true
|
||||
}
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
func GetTempVerifyCode(userId string) (string, bool) {
|
||||
tMu.RLock()
|
||||
defer tMu.RUnlock()
|
||||
|
||||
if v, ok := tempVerifyCodes[userId]; ok {
|
||||
return v.Code, true
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
func RemoveTempVerifyCode(userId string) {
|
||||
tMu.Lock()
|
||||
defer tMu.Unlock()
|
||||
|
||||
delete(tempVerifyCodes, userId)
|
||||
}
|
||||
|
||||
func GetTempVerifyCodes() []structs.TempVerifyCode {
|
||||
tMu.RLock()
|
||||
defer tMu.RUnlock()
|
||||
|
||||
var tempVerifyCodesSlice []structs.TempVerifyCode
|
||||
|
||||
for _, v := range tempVerifyCodes {
|
||||
tempVerifyCodesSlice = append(tempVerifyCodesSlice, v)
|
||||
}
|
||||
|
||||
return tempVerifyCodesSlice
|
||||
}
|
||||
|
||||
func RemoveTempVerifyCodes() {
|
||||
tMu.Lock()
|
||||
defer tMu.Unlock()
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package database
|
|||
import (
|
||||
"fmt"
|
||||
"jannex/telegram-bot-manager/modules/config"
|
||||
"jannex/telegram-bot-manager/modules/structs"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
|
@ -34,4 +35,5 @@ func InitDatabase() {
|
|||
|
||||
DB = db
|
||||
|
||||
db.AutoMigrate(&structs.VerifiedUser{})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package structs
|
||||
|
||||
type NotificationBody struct {
|
||||
UsersIds []string
|
||||
Type uint8
|
||||
Message string
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package structs
|
||||
|
||||
import "time"
|
||||
|
||||
type VerifiedUser struct {
|
||||
UserId string
|
||||
ChatId int
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type VerifyCodeParams struct {
|
||||
UserId string
|
||||
}
|
||||
|
||||
// swagger:response VerifyCodeResponse
|
||||
type VerifyCodeResponse struct {
|
||||
Code string
|
||||
}
|
||||
|
||||
type TempVerifyCode struct {
|
||||
UserId string
|
||||
Code string
|
||||
ExpiredAt time.Time
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
package telegram
|
||||
|
||||
import (
|
||||
"jannex/telegram-bot-manager/modules/cache"
|
||||
"jannex/telegram-bot-manager/modules/database"
|
||||
"jannex/telegram-bot-manager/modules/logger"
|
||||
"jannex/telegram-bot-manager/modules/structs"
|
||||
"jannex/telegram-bot-manager/modules/utils"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var bot *tgbotapi.BotAPI
|
||||
|
||||
func InitBot() {
|
||||
var err error
|
||||
|
||||
bot, err = tgbotapi.NewBotAPI("6450280279:AAGxXdPv_YwRtl_pXIqYojqOecBrEjn3fJo")
|
||||
|
||||
if err != nil {
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to initialize Telegram bot, err: %v", err.Error())
|
||||
log.Fatal().Err(err).Msgf("Failed to initialize Telegram bot, err: %v", err.Error())
|
||||
}
|
||||
|
||||
//bot.Debug = false
|
||||
|
||||
logger.AddSystemLog(rslogger.LogTypeInfo, "Bot connected as %s", bot.Self.UserName)
|
||||
|
||||
go IncomingMessagesHandler()
|
||||
}
|
||||
|
||||
func IncomingMessagesHandler() {
|
||||
updateConfig := tgbotapi.NewUpdate(0)
|
||||
updateConfig.Timeout = 60
|
||||
|
||||
updates, err := bot.GetUpdatesChan(updateConfig)
|
||||
|
||||
if err != nil {
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to get updates from Telegram bot, err: %v", err.Error())
|
||||
log.Fatal().Err(err).Msgf("Failed to get updates from Telegram bot, err: %v", err.Error())
|
||||
}
|
||||
|
||||
for update := range updates {
|
||||
if update.Message == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
chatID := update.Message.Chat.ID
|
||||
text := update.Message.Text
|
||||
|
||||
if text == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
regVerify := regexp.MustCompile(`/verify (\w+)`)
|
||||
regVerifyMatches := regVerify.FindStringSubmatch(text)
|
||||
|
||||
regUnsubscribe := regexp.MustCompile(`/unsubscribe`)
|
||||
|
||||
var replyMessage string
|
||||
|
||||
if len(regVerifyMatches) == 2 {
|
||||
code := regVerifyMatches[1]
|
||||
|
||||
if len(code) != utils.VerifyCodeLength {
|
||||
logger.AddSystemLog(rslogger.LogTypeWarning, "Received code with wrong length from user: %s %s. Message: %s", update.Message.From.FirstName, update.Message.From.LastName, code)
|
||||
continue
|
||||
}
|
||||
|
||||
var userId string
|
||||
var ok bool
|
||||
|
||||
if userId, ok = cache.GetTempVerifyByCode(code); !ok {
|
||||
// code not found in cache
|
||||
|
||||
logger.AddSystemLog(rslogger.LogTypeWarning, "Received code which was not found in cache from user: %s %s. Message: %s", update.Message.From.FirstName, update.Message.From.LastName, code)
|
||||
|
||||
replyMessage = "The code you entered is invalid. Please check the code and try again."
|
||||
} else {
|
||||
// code found in cache
|
||||
|
||||
cache.RemoveTempVerifyCode(userId)
|
||||
|
||||
var foundVerifiedUser structs.VerifiedUser
|
||||
|
||||
res := database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser)
|
||||
|
||||
if res.Error != nil {
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to get verified user from database, err: %v", res.Error.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if foundVerifiedUser.UserId != "" {
|
||||
// user already verified
|
||||
|
||||
replyMessage = "You have already verified your account. You will continue to receive notifications. Type /unsubscribe to stop receiving notifications."
|
||||
|
||||
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to verify his account with code %s, but has already verified his account", update.Message.From.FirstName, update.Message.From.LastName, code)
|
||||
} else {
|
||||
// user not verified
|
||||
|
||||
replyMessage = "You have successfully verified your account. You will now receive notifications. Type /unsubscribe to stop receiving notifications."
|
||||
|
||||
database.DB.Create(&structs.VerifiedUser{
|
||||
UserId: userId,
|
||||
ChatId: update.Message.From.ID,
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
|
||||
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has subscribed to receive notifications", update.Message.From.FirstName, update.Message.From.LastName)
|
||||
}
|
||||
}
|
||||
|
||||
// reply to user
|
||||
reply := tgbotapi.NewMessage(chatID, replyMessage)
|
||||
|
||||
_, err := bot.Send(reply)
|
||||
|
||||
if err != nil {
|
||||
log.Error().Msgf("Failed to send subscribed reply to user, err: %v", err.Error())
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to send reply to user, err: %v", err.Error())
|
||||
}
|
||||
} else if regUnsubscribe.MatchString(text) {
|
||||
res := database.DB.Delete(&structs.VerifiedUser{}, "chat_id = ?", update.Message.From.ID)
|
||||
|
||||
if res.Error != nil {
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to delete verified user from database, err: %v", res.Error.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if res.RowsAffected == 0 {
|
||||
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to unsubscribe from receiving notifications, but has not been verified", update.Message.From.FirstName, update.Message.From.LastName)
|
||||
replyMessage = "You have not been verified yet. Type /verify <code> to start receiving notifications. The code can be found in the user profile on the dashboard."
|
||||
} else {
|
||||
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has unsubscribed from receiving notifications", update.Message.From.FirstName, update.Message.From.LastName)
|
||||
replyMessage = "You have unsubscribed from receiving notifications. Type /verify <code> to start receiving notifications again. The code can be found in the user profile on the dashboard."
|
||||
}
|
||||
|
||||
reply := tgbotapi.NewMessage(chatID, replyMessage)
|
||||
|
||||
_, err := bot.Send(reply)
|
||||
|
||||
if err != nil {
|
||||
logger.AddSystemLog(rslogger.LogTypeError, "Failed to send reply to user, err: %v", err.Error())
|
||||
log.Error().Msgf("Failed to send unsubscribed reply to user, err: %v", err.Error())
|
||||
}
|
||||
} else {
|
||||
logger.AddSystemLog(rslogger.LogTypeWarning, "Received unknown message: %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1,8 @@
|
|||
package utils
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
VerifyCodeLength = 6
|
||||
TempVerifyCodeExpirationTime = 5 * time.Minute
|
||||
)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 665 B |
Binary file not shown.
After Width: | Height: | Size: 628 B |
|
@ -0,0 +1,59 @@
|
|||
html {
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
/* Position the navbar container inside the image */
|
||||
.container {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
margin: 65px 5px;
|
||||
}
|
||||
|
||||
#container-versions {
|
||||
margin: 110px 5px;
|
||||
}
|
||||
|
||||
/* The navbar */
|
||||
.topnav {
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.topnav:first-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Navbar links */
|
||||
.topnav a {
|
||||
float: left;
|
||||
color: #f2f2f2;
|
||||
text-align: center;
|
||||
padding: 10px 12px;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.topnav a:hover {
|
||||
opacity: 0.7;
|
||||
border-bottom: 5px solid #62a03f;
|
||||
}
|
||||
|
||||
.topnav a.active {
|
||||
color: #999494;
|
||||
border-bottom: 5px solid #62a03f;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
|
||||
<link rel="stylesheet" type="text/css" href="index.css" />
|
||||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-initializer.js" charset="UTF-8"> </script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,79 @@
|
|||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1).replace('?', '&');
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
run();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
window.onload = function() {
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: 'swagger.json',
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
});
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,600 @@
|
|||
{
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "JNX Robot Control Manager API Documentation.",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"host": "jannex",
|
||||
"basePath": "/v1",
|
||||
"paths": {
|
||||
"/api/v1/robots": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robots"
|
||||
],
|
||||
"summary": "Get all robots",
|
||||
"operationId": "getRobots",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Page number",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/RobotsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/urobots": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robots"
|
||||
],
|
||||
"summary": "Get all unauthorized robots",
|
||||
"operationId": "getUnauthorizedRobots",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Page number",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/UnauthorizedRobotsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/control/1": {
|
||||
"post": {
|
||||
"description": "This is used to control Rex.\n",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"control"
|
||||
],
|
||||
"summary": "Control Rex.",
|
||||
"operationId": "controlRex",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Control Rex body.",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ControlBody"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Control Rex"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request body"
|
||||
},
|
||||
"422": {
|
||||
"description": "Robot not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/control/1/finish": {
|
||||
"post": {
|
||||
"description": "This is used to finish control Rex.\n",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"control"
|
||||
],
|
||||
"summary": "Finish control Rex.",
|
||||
"operationId": "finishControlRex",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Finish control Rex"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid robot name"
|
||||
},
|
||||
"422": {
|
||||
"description": "Robot not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/permitjoin": {
|
||||
"get": {
|
||||
"description": "This is used to get the current permit join status.\n",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"permitjoin"
|
||||
],
|
||||
"summary": "Get permit join.",
|
||||
"operationId": "getPermitJoin",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Permit join status",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/PermitJoinResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/permitjoin/{enabled}": {
|
||||
"post": {
|
||||
"description": "This is used to enable or disable permit join.\n",
|
||||
"tags": [
|
||||
"permitjoin"
|
||||
],
|
||||
"summary": "Set permit join.",
|
||||
"operationId": "setPermitJoin",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Enable or disable permit join. 0 = disable, 1 = enable.",
|
||||
"name": "enabled",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"enum": [
|
||||
0,
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Permit join set"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request body"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/robot": {
|
||||
"post": {
|
||||
"description": "This is the first request from the robot. It will be used to identify the robot.\n",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "First request from robot.",
|
||||
"operationId": "robotFirstRequest",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "First request body.",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/FirstRequestBody"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Robot identified",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/StatusResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request body"
|
||||
},
|
||||
"403": {
|
||||
"description": "Permit join is enabled"
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "Update robot.",
|
||||
"operationId": "robotUpdate",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Update robot body.",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Robot"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Robot updated"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request body"
|
||||
},
|
||||
"422": {
|
||||
"description": "Robot not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/robot/authorize/{robotId}": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "Authorize robot.",
|
||||
"operationId": "robotAuthorize",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Robot id.",
|
||||
"name": "robotId",
|
||||
"in": "params",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Robot authorized"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid robot id"
|
||||
},
|
||||
"422": {
|
||||
"description": "Robot not found"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/robot/deny/{robotId}": {
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "Deny unauthorized robot.",
|
||||
"operationId": "robotDenyUnauthorizedRobot",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Robot id.",
|
||||
"name": "robotId",
|
||||
"in": "params",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Robot denied"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid robot id"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/robot/fuj/{robotId}": {
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "Free up job from robot.",
|
||||
"operationId": "robotFreeUpJob",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Robot id.",
|
||||
"name": "robotId",
|
||||
"in": "params",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Job freed up"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid robot id"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/robot/{robotId}": {
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"robot"
|
||||
],
|
||||
"summary": "Delete robot.",
|
||||
"operationId": "robotDelete",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Robot id.",
|
||||
"name": "robotId",
|
||||
"in": "params",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Robot deleted"
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid robot id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"APIRobot": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Address": {
|
||||
"type": "string"
|
||||
},
|
||||
"ConnectedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"CreatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"CurrentJobName": {
|
||||
"type": "string"
|
||||
},
|
||||
"FirmwareVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"Id": {
|
||||
"type": "string"
|
||||
},
|
||||
"JobsWaitingCount": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"JobsWaitingNameList": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"Name": {
|
||||
"type": "string"
|
||||
},
|
||||
"Status": {
|
||||
"type": "integer",
|
||||
"format": "uint8"
|
||||
},
|
||||
"Type": {
|
||||
"type": "integer",
|
||||
"format": "uint8"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"ControlBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"JobId": {
|
||||
"type": "string"
|
||||
},
|
||||
"JobName": {
|
||||
"type": "string"
|
||||
},
|
||||
"RobotName": {
|
||||
"type": "string"
|
||||
},
|
||||
"Task": {
|
||||
"$ref": "#/definitions/ControlTask"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"ControlTask": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ConnectedModule": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"X": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Y": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Z": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"FirstRequestBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"FirmwareVersion": {
|
||||
"description": "used firmware version of the robot",
|
||||
"type": "string"
|
||||
},
|
||||
"Id": {
|
||||
"description": "robot id",
|
||||
"type": "string"
|
||||
},
|
||||
"Type": {
|
||||
"description": "robot type",
|
||||
"type": "integer",
|
||||
"format": "uint8"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"PermitJoinResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"RobotsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Robots": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/APIRobot"
|
||||
}
|
||||
},
|
||||
"TotalPages": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"StatusResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Status": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"UnauthorizedRobot": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Address": {
|
||||
"type": "string"
|
||||
},
|
||||
"ConnectedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"CreatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"FirmwareVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"Id": {
|
||||
"type": "string"
|
||||
},
|
||||
"Type": {
|
||||
"type": "integer",
|
||||
"format": "uint8"
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
},
|
||||
"UnauthorizedRobotsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"TotalPages": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"UnauthorizedRobots": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/UnauthorizedRobot"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-go-package": "jannex/robot-control-manager/modules/structs"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package notification
|
||||
|
||||
import (
|
||||
"jannex/telegram-bot-manager/modules/structs"
|
||||
|
||||
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func SendNotification(c *fiber.Ctx) error {
|
||||
var body structs.NotificationBody
|
||||
|
||||
if err := rsutils.BodyParserHelper(c, &body); err != nil {
|
||||
return c.SendStatus(fiber.StatusBadRequest)
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package verifycode
|
||||
|
||||
import (
|
||||
"jannex/telegram-bot-manager/modules/cache"
|
||||
"jannex/telegram-bot-manager/modules/logger"
|
||||
"jannex/telegram-bot-manager/modules/structs"
|
||||
"jannex/telegram-bot-manager/modules/utils"
|
||||
"time"
|
||||
|
||||
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
|
||||
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func GetVerifyCode(c *fiber.Ctx) error {
|
||||
// swagger:operation GET /v1/verifycode/{userId} verifycode getVerifyCode
|
||||
// ---
|
||||
// summary: Get verify code for user
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: userId
|
||||
// in: params
|
||||
// description: User ID
|
||||
// required: true
|
||||
// type: string
|
||||
// responses:
|
||||
// '200':
|
||||
// description: OK
|
||||
// schema:
|
||||
// "$ref": "#/definitions/VerifyCodeResponse"
|
||||
// '400':
|
||||
// description: Bad request
|
||||
// '500':
|
||||
// description: Internal server error
|
||||
|
||||
var params structs.VerifyCodeParams
|
||||
|
||||
if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil {
|
||||
return c.SendStatus(fiber.StatusBadRequest)
|
||||
}
|
||||
|
||||
code, err := rsutils.GenerateCode(6)
|
||||
|
||||
if err != nil {
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
cache.AddTempVerifyCode(structs.TempVerifyCode{
|
||||
UserId: params.UserId,
|
||||
Code: code,
|
||||
ExpiredAt: time.Now().Add(utils.TempVerifyCodeExpirationTime),
|
||||
})
|
||||
|
||||
logger.AddSystemLog(rslogger.LogTypeInfo, "Generated verify code for user %s", params.UserId)
|
||||
|
||||
return c.JSON(structs.VerifyCodeResponse{Code: code})
|
||||
}
|
|
@ -1,8 +1,18 @@
|
|||
package router
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
import (
|
||||
"jannex/telegram-bot-manager/routers/api/v1/verifycode"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func SetupRoutes(app *fiber.App) {
|
||||
//v1 := app.Group("/v1")
|
||||
v1 := app.Group("/v1")
|
||||
|
||||
vc := v1.Group("/verifycode")
|
||||
vc.Get("/:userId", verifycode.GetVerifyCode)
|
||||
|
||||
n := v1.Group("/notification")
|
||||
|
||||
app.Static("/", "./public/")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue