diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index 914b23d..e98ad1d 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -18,11 +18,12 @@ jobs: run: go build -v ./... - name: Build Servers run: | - go build -v -ldflags "-s -w" ./servers/bullion/main-server/main.go - go build -v -ldflags "-s -w" ./servers/jwelly/mysql-to-surreal/main.go - go build -v -ldflags "-s -w" ./servers/jwelly/main-server/main.go - go build -v -ldflags "-s -w" ./servers/jwelly/mysql-backup/main.go - go build -v -ldflags "-s -w" ./servers/jwelly/mysql-to-mysql/main.go - go build -v -ldflags "-s -w" ./servers/link-shortner/main.go - go build -v -ldflags "-s -w" ./servers/whatsapp-server/main.go - go build -v -ldflags "-s -w" ./servers/http-dump/dump-server/main.go + go build -ldflags "-s -w" -v ./servers/bullion/main-server/main.go + go build -ldflags "-s -w" -v ./servers/jwelly/mysql-to-surreal/main.go + go build -ldflags "-s -w" -v ./servers/jwelly/main-server/main.go + go build -ldflags "-s -w" -v ./servers/jwelly/mysql-backup/main.go + go build -ldflags "-s -w" -v ./servers/jwelly/mysql-to-mysql/main.go + go build -ldflags "-s -w" -v ./servers/link-shortner/main.go + go build -ldflags "-s -w" -v ./servers/whatsapp-server/main.go + go build -ldflags "-s -w" -v ./servers/telegram-server/main.go + go build -ldflags "-s -w" -v ./servers/http-dump/dump-server/main.go diff --git a/.vscode/launch.json b/.vscode/launch.json index e6cd453..f0e4c99 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,14 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Run Telegram Server", + "type": "go", + "request": "launch", + "mode": "auto", + "args": ["--dev"], + "program": "${workspaceFolder}/servers/telegram-server/main.go" + }, { "name": "Run Bullion Server", "type": "go", @@ -18,7 +26,15 @@ "request": "launch", "mode": "auto", "args": ["--dev"], - "program": "${workspaceFolder}/servers/http-dump-server/main.go" + "program": "${workspaceFolder}/servers/http-dump/dump-server/main.go" + }, + { + "name": "Run Message Dump Server", + "type": "go", + "request": "launch", + "mode": "auto", + "args": ["--dev"], + "program": "${workspaceFolder}/servers/http-dump/message-dump/main.go" }, { "name": "Run Whatsapp Server", @@ -67,6 +83,14 @@ "mode": "auto", "args": ["--dev"], "program": "${workspaceFolder}/servers/jwelly/mysql-to-mysql/main.go" + }, + { + "name": "Run TEST", + "type": "go", + "request": "launch", + "mode": "auto", + "args": ["--dev"], + "program": "${workspaceFolder}/test.go" } ] } diff --git a/go.mod b/go.mod index cc151cf..74c2dfe 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,9 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 github.com/gen2brain/go-fitz v1.24.15 github.com/go-faker/faker/v4 v4.7.0 - github.com/go-playground/validator/v10 v10.29.0 + github.com/go-playground/validator/v10 v10.30.1 github.com/go-sql-driver/mysql v1.9.3 + github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/gofiber/fiber/v2 v2.52.10 github.com/golang-jwt/jwt/v5 v5.3.0 github.com/google/uuid v1.6.0 @@ -26,7 +27,7 @@ require ( go.mau.fi/whatsmeow v0.0.0-20251217143725-11cf47c62d32 go.mongodb.org/mongo-driver v1.17.6 golang.org/x/crypto v0.46.0 - google.golang.org/api v0.257.0 + google.golang.org/api v0.258.0 google.golang.org/protobuf v1.36.11 ) @@ -102,7 +103,7 @@ require ( go.opentelemetry.io/otel/sdk v1.39.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect - golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect golang.org/x/image v0.34.0 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect @@ -112,9 +113,9 @@ require ( golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/appengine/v2 v2.0.6 // indirect - google.golang.org/genproto v0.0.0-20251213004720-97cd9d5aeac2 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect - google.golang.org/grpc v1.77.0 // indirect + google.golang.org/genproto v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.78.0 // indirect rsc.io/qr v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index 529f6d4..de499ac 100644 --- a/go.sum +++ b/go.sum @@ -102,10 +102,12 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o 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.29.0 h1:lQlF5VNJWNlRbRZNeOIkWElR+1LL/OuHcc0Kp14w1xk= -github.com/go-playground/validator/v10 v10.29.0/go.mod h1:D6QxqeMlgIPuT02L66f2ccrZ7AGgHkzKmmTMZhk/Kc4= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.52.10 h1:jRHROi2BuNti6NYXmZ6gbNSfT3zj/8c0xy94GOU5elY= github.com/gofiber/fiber/v2 v2.52.10/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= @@ -242,8 +244,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= -golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8= golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU= @@ -289,18 +291,18 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA= -google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4= +google.golang.org/api v0.258.0 h1:IKo1j5FBlN74fe5isA2PVozN3Y5pwNKriEgAXPOkDAc= +google.golang.org/api v0.258.0/go.mod h1:qhOMTQEZ6lUps63ZNq9jhODswwjkjYYguA7fA3TBFww= google.golang.org/appengine/v2 v2.0.6 h1:LvPZLGuchSBslPBp+LAhihBeGSiRh1myRoYK4NtuBIw= google.golang.org/appengine/v2 v2.0.6/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI= -google.golang.org/genproto v0.0.0-20251213004720-97cd9d5aeac2 h1:stRtB2UVzFOWnorVuwF0BVVEjQ3AN6SjHWdg811UIQM= -google.golang.org/genproto v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= -google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= -google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= +google.golang.org/genproto v0.0.0-20251222181119-0a764e51fe1b h1:kqShdsddZrS6q+DGBCA73CzHsKDu5vW4qw78tFnbVvY= +google.golang.org/genproto v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:gw1DtiPCt5uh/HV9STVEeaO00S5ATsJiJ2LsZV8lcDI= +google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E= +google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/http-dump b/http-dump deleted file mode 100755 index d98bb0e..0000000 Binary files a/http-dump and /dev/null differ diff --git a/linux.sh b/linux.sh new file mode 100755 index 0000000..47760db --- /dev/null +++ b/linux.sh @@ -0,0 +1,2 @@ +GOOS=linux GOARCH=amd64 go build -v -o http-dump -ldflags="-s -w" ./servers/http-dump/dump-server/main.go +GOOS=linux GOARCH=amd64 go build -v -o message-dump -ldflags="-s -w" ./servers/http-dump/message-dump/main.go \ No newline at end of file diff --git a/servers/http-dump/dump-server/interfaces/admin-user.entity.go b/servers/http-dump/dump-server/interfaces/end-point.entity.go similarity index 100% rename from servers/http-dump/dump-server/interfaces/admin-user.entity.go rename to servers/http-dump/dump-server/interfaces/end-point.entity.go diff --git a/servers/http-dump/message-dump/env/index.go b/servers/http-dump/message-dump/env/index.go new file mode 100644 index 0000000..3672d27 --- /dev/null +++ b/servers/http-dump/message-dump/env/index.go @@ -0,0 +1,26 @@ +package messagedump_env + +import "github.com/rpsoftech/golang-servers/env" + +type dumpEnv struct { + DefaultEnv *env.DefaultEnvInterface + REDIS_DEFAULT_KEY string `json:"REDIS_DEFAULT_KEY" validate:"required,min=3"` + REDIS_DEFAULT_CHANNEL string `json:"REDIS_DEFAULT_CHANNEL" validate:"required,min=3"` + ServerId string `json:"SERVER_ID" validate:"required,min=3"` +} + +var Env *dumpEnv + +func init() { + env.LoadEnv("message-dump.env") + println("Dump Server Env Initialized") + Env = &dumpEnv{ + DefaultEnv: env.Env, + REDIS_DEFAULT_KEY: env.Env.GetEnv("REDIS_DEFAULT_KEY"), + REDIS_DEFAULT_CHANNEL: env.Env.GetEnv("REDIS_DEFAULT_CHANNEL"), + ServerId: env.Env.GetEnv("SERVER_ID"), + // ACCESS_TOKEN_KEY: env.Env.GetEnv("ACCESS_TOKEN_KEY"), + // REFRESH_TOKEN_KEY: env.Env.GetEnv("REFRESH_TOKEN_KEY"), + } + env.ValidateEnv(Env) +} diff --git a/servers/http-dump/message-dump/env/redis.key-env.go b/servers/http-dump/message-dump/env/redis.key-env.go new file mode 100644 index 0000000..fce5289 --- /dev/null +++ b/servers/http-dump/message-dump/env/redis.key-env.go @@ -0,0 +1,10 @@ +package messagedump_env + +import "fmt" + +func GetRedisKey(key string) string { + return fmt.Sprintf("%s%s", Env.REDIS_DEFAULT_KEY, key) +} +func GetRedisEventKey(key string) string { + return fmt.Sprintf("%s%s", Env.REDIS_DEFAULT_CHANNEL, key) +} diff --git a/servers/http-dump/message-dump/interfaces/config.interfaces.go b/servers/http-dump/message-dump/interfaces/config.interfaces.go new file mode 100644 index 0000000..b08dc2b --- /dev/null +++ b/servers/http-dump/message-dump/interfaces/config.interfaces.go @@ -0,0 +1,29 @@ +package messagedump_interfaces + +import "github.com/rpsoftech/golang-servers/interfaces" + +// type DumpConfig struct{} + +type MessageDumpServerConfig struct { + *interfaces.BaseEntity `bson:",inline"` + Name string `bson:"name" json:"name" validate:"required,min=3,max=100"` + MessageDumpConfigs []MessageDumpConfig `bson:"messageDumpConfigs" json:"messageDumpConfigs" validate:"required,dive"` +} + +type MessageDumpConfig struct { + // *interfaces.BaseEntity `bson:",inline"` + SourceChannel string `bson:"sourceChannel" json:"sourceChannel" validate:"required,oneof=whatsapp"` + WhatsappConfig *WhatsappSideConfig `bson:"whatsappConfig" json:"whatsappConfig" validate:"required,dive"` + TelegramConfig *TelegramSideConfig `bson:"telegramConfig" json:"telegramConfig" validate:"required,dive"` +} + +type WhatsappSideConfig struct { + WhatsappServerToken string `bson:"whatsappServerToken" json:"whatsappServerToken" validate:"required"` + WhatsappServerUrl string `bson:"whatsappServerUrl" json:"whatsappServerUrl" validate:"required,url"` + SendNumbers []string `bson:"sendNumbers" json:"sendNumbers" validate:"required"` + SendWhatsappId []string `bson:"sendWhatsappId" json:"sendWhatsappId" validate:"required"` +} +type TelegramSideConfig struct { + TelegramBotToken string `bson:"telegramBotToken" json:"telegramBotToken" validate:"required"` + UserChatId []int64 `bson:"userChatId" json:"userChatId" validate:"required"` +} diff --git a/servers/http-dump/message-dump/main.go b/servers/http-dump/message-dump/main.go new file mode 100644 index 0000000..623eac1 --- /dev/null +++ b/servers/http-dump/message-dump/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "sync" + + _ "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/env" + messagedump_env "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/env" + messagedump_interfaces "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/interfaces" + messagedump_repo "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/repo" + messagedump_telegram "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/telegram" + messagedump_whatsapp "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/whatsapp" + "github.com/rpsoftech/golang-servers/utility/mongodb" + "github.com/rpsoftech/golang-servers/utility/redis" +) + +func deferMainFunc() { + println("Closing...") + redis.DeferFunction() + mongodb.DeferFunction() +} +func main() { + defer deferMainFunc() + println("Message Dump Server Started") + println("Getting Details From MONGO") + repo := messagedump_repo.InitAndReturnMessageDumpConfigRepo() + res, err := repo.FindOne(messagedump_env.Env.ServerId) + if err != nil { + panic(err) + } + var wg sync.WaitGroup // Declare a WaitGroup + // red: + println("Config Name:", res.Name) + println("Number of Message Dump Configs:", len(res.MessageDumpConfigs)) + for _, config := range res.MessageDumpConfigs { + // println("Config Name:", config.) + wg.Add(1) + go func(config *messagedump_interfaces.MessageDumpConfig) { + pubSub := redis.InitRedisAndRedisClient().SubscribeToChannels(messagedump_env.GetRedisEventKey(fmt.Sprintf("d/%s", config.SourceChannel))) + var teleBot *messagedump_telegram.TelegramBotInstance + var whatsappBot *messagedump_whatsapp.WhatsappBotInstance + var err error + if config.TelegramConfig.TelegramBotToken != "" { + println("Telegram Bot Token Found:") + teleBot, err = messagedump_telegram.CreateTelegramBotInstance(config.TelegramConfig.TelegramBotToken) + if err != nil { + panic(err) + } + } + if config.WhatsappConfig.WhatsappServerUrl != "" && config.WhatsappConfig.WhatsappServerToken != "" { + println("WhatsApp Server URL:", config.WhatsappConfig.WhatsappServerUrl) + whatsappBot = messagedump_whatsapp.CreateWhatsappBotInstance(config.WhatsappConfig.WhatsappServerUrl, config.WhatsappConfig.WhatsappServerToken) + } + ch := pubSub.Channel() + for msg := range ch { + if teleBot != nil && teleBot.Bot != nil { + for _, chatId := range config.TelegramConfig.UserChatId { + teleBot.Bot.SendMessage(chatId, msg.Payload) + } + } + if whatsappBot != nil { + whatsappBot.SendTextMessage(config.WhatsappConfig.SendNumbers, msg.Payload) + } + fmt.Printf("Message from channel %s: %s\n", msg.Channel, msg.Payload) + } + wg.Done() + }(&config) + } + wg.Wait() // Wait for all goroutines to finish + fmt.Println("All workers have completed their tasks. Main function exiting.") +} diff --git a/servers/http-dump/message-dump/repo/config.repo.go b/servers/http-dump/message-dump/repo/config.repo.go new file mode 100644 index 0000000..b1c485d --- /dev/null +++ b/servers/http-dump/message-dump/repo/config.repo.go @@ -0,0 +1,61 @@ +package messagedump_repo + +import ( + "errors" + "fmt" + "net/http" + + "github.com/rpsoftech/golang-servers/interfaces" + messagedump_interfaces "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/interfaces" + "github.com/rpsoftech/golang-servers/utility/mongodb" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +type MessageDumpConfigRepoStruct struct { + collection *mongo.Collection +} + +const messageDumpConfigCollectionName = "MessageDumpConfigs" + +var messageDumpConfigRepo *MessageDumpConfigRepoStruct + +func InitAndReturnMessageDumpConfigRepo() *MessageDumpConfigRepoStruct { + if messageDumpConfigRepo != nil { + return messageDumpConfigRepo + } + coll := mongodb.MongoDatabase.Collection(messageDumpConfigCollectionName) + messageDumpConfigRepo = &MessageDumpConfigRepoStruct{ + collection: coll, + } + mongodb.AddUniqueIndexesToCollection([]string{"id"}, messageDumpConfigRepo.collection) + return messageDumpConfigRepo +} + +func (repo *MessageDumpConfigRepoStruct) FindOne(id string) (*messagedump_interfaces.MessageDumpServerConfig, error) { + result := new(messagedump_interfaces.MessageDumpServerConfig) + + err := repo.collection.FindOne(mongodb.MongoCtx, bson.D{{ + Key: "id", Value: id, + }}).Decode(result) + + if err != nil { + if errors.Is(err, mongo.ErrNoDocuments) { + // This error means your query did not match any documents. + err = &interfaces.RequestError{ + StatusCode: http.StatusBadRequest, + Code: interfaces.ERROR_ENTITY_NOT_FOUND, + Message: fmt.Sprintf("Product Entity identified by id %s not found", id), + Name: "ENTITY_NOT_FOUND", + } + } else { + err = &interfaces.RequestError{ + StatusCode: 500, + Code: interfaces.ERROR_INTERNAL_SERVER, + Message: fmt.Sprintf("Internal Server Error: %s", err.Error()), + Name: "INTERNAL_ERROR", + } + } + } + return result, err +} diff --git a/servers/http-dump/message-dump/telegram/index.go b/servers/http-dump/message-dump/telegram/index.go new file mode 100644 index 0000000..4d663bb --- /dev/null +++ b/servers/http-dump/message-dump/telegram/index.go @@ -0,0 +1,29 @@ +package messagedump_telegram + +import ( + messagedump_interfaces "github.com/rpsoftech/golang-servers/servers/http-dump/message-dump/interfaces" + "github.com/rpsoftech/golang-servers/telegram" +) + +type TelegramBotInstance struct { + Bot *telegram.TelegramBot + config *messagedump_interfaces.TelegramSideConfig +} + +var telegramBotsMap = make(map[string]*TelegramBotInstance) + +func CreateTelegramBotInstance(token string) (*TelegramBotInstance, error) { + // bot, err := tgbotapi.NewBotAPI(token) + // if err != nil { + // return nil, err + // } + // return &TelegramBotInstance{BotAPI: bot}, nil + if bot, exists := telegramBotsMap[token]; exists { + return bot, nil + } + b := telegram.InitAndReturnTelegramBOT(token) + bot := &TelegramBotInstance{Bot: b} + go bot.Bot.UserIdListner() + telegramBotsMap[token] = bot + return bot, nil +} diff --git a/servers/http-dump/message-dump/whatsapp/index.go b/servers/http-dump/message-dump/whatsapp/index.go new file mode 100644 index 0000000..2d86362 --- /dev/null +++ b/servers/http-dump/message-dump/whatsapp/index.go @@ -0,0 +1,60 @@ +package messagedump_whatsapp + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" +) + +type WhatsappBotInstance struct { + URL string `json:"url" validate:"required"` + Token string `json:"token" validate:"required"` + sendMessageUrl string + sendMediaUrl string +} + +func (w *WhatsappBotInstance) SendTextMessage(numbers []string, msg string) bool { + postBody, _ := json.Marshal(map[string]any{ + "to": numbers, + "msg": msg, + }) + payload := bytes.NewBuffer(postBody) + + client := &http.Client{} + req, err := http.NewRequest("POST", w.sendMessageUrl, payload) + + if err != nil { + fmt.Println(err) + return false + } + req.Header.Add("Content-Type", "application/json") + req.Header.Add("X-Api-Token", w.Token) + + res, err := client.Do(req) + if err != nil { + fmt.Println(err) + return false + } + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + if err != nil { + fmt.Println(err) + return false + } + bodyString := string(body) + println(bodyString) + return !strings.Contains(bodyString, "false") +} + +func CreateWhatsappBotInstance(url string, token string) *WhatsappBotInstance { + return &WhatsappBotInstance{ + URL: url, + Token: token, + sendMessageUrl: fmt.Sprintf("%s/send_message", url), + sendMediaUrl: fmt.Sprintf("%s/send_media", url), + } +} diff --git a/servers/telegram-server/.gitignore b/servers/telegram-server/.gitignore new file mode 100644 index 0000000..710ff81 --- /dev/null +++ b/servers/telegram-server/.gitignore @@ -0,0 +1,2 @@ +*.db +server.config.json \ No newline at end of file diff --git a/servers/telegram-server/apis/index.go b/servers/telegram-server/apis/index.go new file mode 100644 index 0000000..4249530 --- /dev/null +++ b/servers/telegram-server/apis/index.go @@ -0,0 +1,242 @@ +package telegram_server_apis + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/gofiber/fiber/v2" + "github.com/rpsoftech/golang-servers/interfaces" + telegram_server_middleware "github.com/rpsoftech/golang-servers/servers/telegram-server/middleware" + telegram_config "github.com/rpsoftech/golang-servers/servers/telegram-server/telegram" + telegram_server "github.com/rpsoftech/golang-servers/servers/telegram-server/telegram" + + // "github.com/rpsoftech/golang-servers/servers/whatsapp-server/src/whatsapp" + utility_functions "github.com/rpsoftech/golang-servers/utility/functions" +) + +type ( + apiSendMessage struct { + To []int64 `json:"to" validate:"required,dive,min=1"` + Msg string `json:"msg"` + } + // apiSendMediaMsgWithBase64 struct { + // apiSendMessage + // FileName string `json:"fileName" validate:"required,min=3"` + // Base64 string `json:"base64" validate:"required,min=3"` + // } +) + +func AddApis(app fiber.Router) { + authenticated := app.Group("", telegram_server_middleware.AllowOnlyValidLoggedInWhatsapp) + authenticated.Post("/send_message", SendMessage) + // authenticated.Post("/send_media", SendMediaFile) + // authenticated.Post("/send_media_64", SendMediaFileWithBase64) +} +func SendMessage(c *fiber.Ctx) error { + body := new(apiSendMessage) + c.BodyParser(body) + + if err := utility_functions.ValidateReqInput(body); err != nil { + return err + } + if len(body.To) == 0 || len(strconv.FormatInt(body.To[0], 10)) < 7 { + return &interfaces.RequestError{ + StatusCode: http.StatusBadRequest, + Code: interfaces.ERROR_INVALID_INPUT, + Message: "Number Not Found", + Name: "ERROR_INVALID_INPUT", + } + } + token, err := telegram_server.ExtractNumberFromCtx(c) + if err != nil { + return err + } + if len(body.Msg) == 0 { + return &interfaces.RequestError{ + StatusCode: http.StatusBadRequest, + Code: interfaces.ERROR_INVALID_INPUT, + Message: "Message Not Found", + Name: "ERROR_INVALID_INPUT", + } + } + connection := telegram_config.ConnectionMap.GetBotConnection(token) + if connection == nil { + return &interfaces.RequestError{ + StatusCode: http.StatusNotFound, + Code: interfaces.ERROR_CONNECTION_NOT_FOUND, + Message: fmt.Sprintf("Number %s Not Found", token), + Name: "ERROR_CONNECTION_NOT_FOUND", + } + } + // runHeadLess := true + runHeadLess, err := strconv.ParseBool(telegram_server.ExtractKeyFromHeader(c, "Headless")) + if err != nil { + runHeadLess = false + } + if runHeadLess { + go connection.SendMessage(body.To, body.Msg) + return c.JSON(fiber.Map{ + "success": true, + }) + } else { + return c.JSON(connection.SendMessage(body.To, body.Msg)) + } +} + +// func SendMediaFile(c *fiber.Ctx) error { +// body := new(apiSendMessage) +// c.BodyParser(body) +// number, err := whatsapp_functions.ExtractNumberFromCtx(c) +// if err != nil { +// return err +// } +// file, err := c.FormFile("file") +// if err != nil { +// return &interfaces.RequestError{ +// StatusCode: http.StatusBadRequest, +// Code: interfaces.ERROR_INVALID_INPUT, +// Message: "File Not Found", +// Name: "ERROR_INVALID_INPUT", +// Extra: err, +// } +// } +// json.Unmarshal([]byte(c.FormValue("to", "[]")), &body.To) +// json.Unmarshal([]byte(c.FormValue("msg", "")), &body.Msg) +// if err := utility_functions.ValidateReqInput(body); err != nil { +// return err +// } + +// if len(body.To) == 0 || len(body.To[0]) < 7 { +// return &interfaces.RequestError{ +// StatusCode: http.StatusBadRequest, +// Code: interfaces.ERROR_INVALID_INPUT, +// Message: "Number Not Found", +// Name: "ERROR_INVALID_INPUT", +// } +// } +// connection, ok := whatsapp.ConnectionMap[number] +// if !ok || connection == nil { +// return &interfaces.RequestError{ +// StatusCode: http.StatusNotFound, +// Code: interfaces.ERROR_CONNECTION_NOT_FOUND, +// Message: fmt.Sprintf("Number %s Not Found", number), +// Name: "ERROR_CONNECTION_NOT_FOUND", +// } +// } +// err = connection.ReturnStatusError() +// if err != nil { +// return err +// } + +// destination := fmt.Sprintf("./tmp/%s", file.Filename) +// if err := c.SaveFile(file, destination); err != nil { +// return &interfaces.RequestError{ +// StatusCode: http.StatusBadRequest, +// Code: interfaces.ERROR_INTERNAL_SERVER, +// Message: "Error While Saving File", +// Name: "ERROR_INTERNAL_SERVER", +// Extra: err, +// } +// } +// runHeadLess, err := strconv.ParseBool(whatsapp_functions.ExtractKeyFromHeader(c, "Headless")) +// if err != nil { +// runHeadLess = false +// } +// if runHeadLess { +// go connection.SendMediaFileWithPath(body.To, destination, file.Filename, body.Msg) +// return c.JSON(fiber.Map{ +// "success": true, +// }) +// } else { +// return c.JSON(connection.SendMediaFileWithPath(body.To, destination, file.Filename, body.Msg)) +// } +// } +// func SendMediaFileWithBase64(c *fiber.Ctx) error { +// body := new(apiSendMediaMsgWithBase64) +// c.BodyParser(body) + +// if err := utility_functions.ValidateReqInput(body); err != nil { +// return err +// } + +// if len(body.To) == 0 || len(body.To[0]) < 7 { +// return &interfaces.RequestError{ +// StatusCode: http.StatusBadRequest, +// Code: interfaces.ERROR_INVALID_INPUT, +// Message: "Number Not Found", +// Name: "ERROR_INVALID_INPUT", +// } +// } +// number, err := whatsapp_functions.ExtractNumberFromCtx(c) +// if err != nil { +// return err +// } + +// connection, ok := whatsapp.ConnectionMap[number] +// if !ok || connection == nil { +// return &interfaces.RequestError{ +// StatusCode: http.StatusNotFound, +// Code: interfaces.ERROR_CONNECTION_NOT_FOUND, +// Message: fmt.Sprintf("Number %s Not Found", number), +// Name: "ERROR_CONNECTION_NOT_FOUND", +// } +// } +// err = connection.ReturnStatusError() +// if err != nil { +// return err +// } +// runHeadLess, err := strconv.ParseBool(whatsapp_functions.ExtractKeyFromHeader(c, "Headless")) +// if err != nil { +// runHeadLess = false +// } +// if runHeadLess { +// go connection.SendMediaFileBase64(body.To, body.Base64, body.FileName, body.Msg) +// return c.JSON(fiber.Map{ +// "success": true, +// }) +// } else { +// return c.JSON(connection.SendMediaFileBase64(body.To, body.Base64, body.FileName, body.Msg)) +// } +// } + +// GetQrCode returns the QR Code of the connection based on the number in the request context +// @Summary Returns the QR Code of the connection +// @Description Returns the QR Code of the connection based on the number in the request context +// @Tags Connection +// @Accept json +// @Produce json +// @Param number path string true "Number" +// @Success 200 {object} fiber.Map{qrCode string} +// @Success 200 {object} fiber.Map{success bool} +// @Failure 404 {object} interfaces.RequestError +// @Failure 500 {object} interfaces.RequestError +// @Router /connections/{number}/qrcode [get] +// func GetQrCode(c *fiber.Ctx) error { +// number, err := telegram_server.ExtractNumberFromCtx(c) +// if err != nil { +// return err +// } + +// connection, ok := whatsapp.ConnectionMap[number] +// if !ok || connection == nil { +// return &interfaces.RequestError{ +// StatusCode: http.StatusNotFound, +// Code: interfaces.ERROR_CONNECTION_NOT_FOUND, +// Message: fmt.Sprintf("Number %s Not Found", number), +// Name: "ERROR_CONNECTION_NOT_FOUND", +// } +// } +// err = connection.ReturnStatusError() + +// if err != nil { +// png, _ := qrcode.Encode(connection.QrCodeString, qrcode.High, 512) +// return c.JSON(fiber.Map{ +// "qrCode": base64.StdEncoding.EncodeToString(png), +// "qrCodeData": connection.QrCodeString, +// }) +// } +// return c.JSON(fiber.Map{ +// "success": true, +// }) +// } diff --git a/servers/telegram-server/config/config-key.go b/servers/telegram-server/config/config-key.go new file mode 100644 index 0000000..033143e --- /dev/null +++ b/servers/telegram-server/config/config-key.go @@ -0,0 +1,8 @@ +package telegram_server_config + +const ( + REQ_LOCAL_KEY_ROLE = "UserRole" + REQ_LOCAL_ERROR_KEY = "Error" + REQ_LOCAL_NUMBER_KEY = "Number" + REQ_LOCAL_KEY_TOKEN_RAW_DATA = "TokenRawData" +) diff --git a/servers/telegram-server/config/index.go b/servers/telegram-server/config/index.go new file mode 100644 index 0000000..7ad84c5 --- /dev/null +++ b/servers/telegram-server/config/index.go @@ -0,0 +1,65 @@ +package telegram_server_config + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/rpsoftech/golang-servers/env" + utility_functions "github.com/rpsoftech/golang-servers/utility/functions" + "github.com/rpsoftech/golang-servers/validator" +) + +var ( + TelegramBotConfigMap = &IServerConfig{} + CurrentDirectory string = "" + serverConfigFilePath string = "" +) + +const ServerConfigFileName = "server.config.json" + +type IServerConfig struct { + Tokens map[string]string `json:"tokens" validate:"required"` +} + +func init() { + CurrentDirectory = env.FindAndReturnCurrentDir() + TelegramBotConfigMap = ReadConfigFileAndReturnIt(CurrentDirectory) +} + +func (sc *IServerConfig) Save() { + if serverConfigFilePath == "" { + serverConfigFilePath = filepath.Join(CurrentDirectory, ServerConfigFileName) + } + byteJson, err := json.MarshalIndent(sc, "", " ") + if err != nil { + return + } + f, err := os.OpenFile(serverConfigFilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + if err != nil { + fmt.Printf("%v \n", err) + return + } + defer f.Close() + if _, err = f.Write(byteJson); err != nil { + fmt.Printf("%v \n", err) + } +} + +func ReadConfigFileAndReturnIt(currentDir string) *IServerConfig { + config := new(IServerConfig) + configFilePAth := filepath.Join(currentDir, ServerConfigFileName) + if _, err := utility_functions.Exist(configFilePAth); errors.Is(err, os.ErrNotExist) { + panic(fmt.Errorf("CONFIG_NOT_EXIST_ON_PATH %s", configFilePAth)) + } + dat, err := os.ReadFile(configFilePAth) + env.Check(err) + err = json.Unmarshal(dat, config) + env.Check(err) + if errs := validator.Validator.Validate(config); len(errs) > 0 { + panic(fmt.Errorf("CONFIG_ERROR %#v", errs)) + } + return config +} diff --git a/servers/telegram-server/main.go b/servers/telegram-server/main.go new file mode 100644 index 0000000..585c3c9 --- /dev/null +++ b/servers/telegram-server/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/logger" + "github.com/rpsoftech/golang-servers/env" + "github.com/rpsoftech/golang-servers/interfaces" + telegram_server_apis "github.com/rpsoftech/golang-servers/servers/telegram-server/apis" + telegram_server_config "github.com/rpsoftech/golang-servers/servers/telegram-server/config" + telegram_server_middleware "github.com/rpsoftech/golang-servers/servers/telegram-server/middleware" + telegram_config "github.com/rpsoftech/golang-servers/servers/telegram-server/telegram" + telegram_server "github.com/rpsoftech/golang-servers/servers/telegram-server/telegram" + "github.com/rpsoftech/golang-servers/telegram" + utility_functions "github.com/rpsoftech/golang-servers/utility/functions" +) + +var version string + +func main() { + env.LoadEnv("telegram-server.env") + println(version) + go func() { + os.RemoveAll("./tmp") + os.Mkdir("./tmp", 0777) + }() + outputLogFolderDir := filepath.Join(env.FindAndReturnCurrentDir(), "telegram_server_logs") + if _, err := utility_functions.Exist(outputLogFolderDir); errors.Is(err, os.ErrNotExist) { + os.MkdirAll(outputLogFolderDir, 0777) + } + telegram_config.OutPutFilePath = ReturnOutPutFilePath(env.FindAndReturnCurrentDir()) + go func() { + for i, t := range telegram_server_config.TelegramBotConfigMap.Tokens { + println(i, t) + bot := telegram.InitAndReturnTelegramBOT(t) + go bot.UserIdListner() + telegram_server.ConnectionMap.AddBotConnection(i, telegram_server.CreateTelegramBot(t, bot)) + } + // telegram_config.ConnectionMap + }() + InitFiberServer() + +} + +func InitFiberServer() { + app := fiber.New(fiber.Config{ + BodyLimit: 200 * 1024 * 1024, + ErrorHandler: func(c *fiber.Ctx, err error) error { + mappedError, ok := err.(*interfaces.RequestError) + if !ok { + println(err.Error()) + return c.Status(500).JSON(interfaces.RequestError{ + Code: interfaces.ERROR_INTERNAL_SERVER, + Message: "Some Internal Error", + Name: "Global Error Handler Function", + }) + } + return c.Status(mappedError.StatusCode).JSON(mappedError) + }, + }) + app.Use(logger.New()) + app.Static("/swagger", "./swagger") + telegram_server_apis.AddApis(app.Group("/v1", telegram_server_middleware.TokenDecrypter, telegram_server_middleware.AllowOnlyValidTokenMiddleWare)) + app.Use(func(c *fiber.Ctx) error { + return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!") + }) + hostAndPort := "" + if env.Env.APP_ENV == env.APP_ENV_LOCAL || env.Env.APP_ENV == env.APP_ENV_DEVELOPE { + hostAndPort = "127.0.0.1" + } + hostAndPort = hostAndPort + ":" + env.GetServerPort(env.PORT_KEY) + app.Listen(hostAndPort) +} + +func ReturnOutPutFilePath(currentDir string) string { + t := time.Now() + today := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, t.Nanosecond(), t.Location()).Unix() + return filepath.Join(currentDir, fmt.Sprintf("%d.log.csv", today)) +} diff --git a/servers/telegram-server/middleware/token-validator.go b/servers/telegram-server/middleware/token-validator.go new file mode 100644 index 0000000..7a0dbc7 --- /dev/null +++ b/servers/telegram-server/middleware/token-validator.go @@ -0,0 +1,91 @@ +package telegram_server_middleware + +import ( + "github.com/gofiber/fiber/v2" + "github.com/rpsoftech/golang-servers/env" + "github.com/rpsoftech/golang-servers/interfaces" + telegram_server_config "github.com/rpsoftech/golang-servers/servers/telegram-server/config" +) + +// fiber middleware for jwt +func TokenDecrypter(c *fiber.Ctx) error { + reqHeaders := c.GetReqHeaders() + println(c.IP()) + tokenString, foundToken := reqHeaders[env.RequestTokenHeaderKey] + if !foundToken || len(tokenString) != 1 || tokenString[0] == "" { + c.Locals(interfaces.REQ_LOCAL_ERROR_KEY, &interfaces.RequestError{ + StatusCode: 403, + Code: interfaces.ERROR_TOKEN_NOT_BEFORE, + Message: "Please Pass Valid Token", + Name: "ERROR_TOKEN_NOT_PASSED", + }) + return c.Next() + } + if _, ok := telegram_server_config.TelegramBotConfigMap.Tokens[tokenString[0]]; !ok { + c.Locals(interfaces.REQ_LOCAL_ERROR_KEY, &interfaces.RequestError{ + StatusCode: 401, + Code: interfaces.ERROR_INVALID_TOKEN, + Message: "Invalid Token", + Name: "ERROR_INVALID_TOKEN", + }) + } else { + c.Locals(telegram_server_config.REQ_LOCAL_NUMBER_KEY, tokenString[0]) + } + return c.Next() +} + +func AllowOnlyValidTokenMiddleWare(c *fiber.Ctx) error { + jwtRawFromLocal := c.Locals(telegram_server_config.REQ_LOCAL_NUMBER_KEY) + localError := c.Locals(interfaces.REQ_LOCAL_ERROR_KEY) + + if jwtRawFromLocal == nil { + if localError != nil { + err, ok := localError.(*interfaces.RequestError) + if !ok { + return &interfaces.RequestError{ + StatusCode: 403, + Code: interfaces.ERROR_INTERNAL_SERVER, + Message: "Cannot Cast Error Token", + Name: "NOT_VALID_DECRYPTED_TOKEN", + } + } + return err + } + return &interfaces.RequestError{ + StatusCode: 403, + Code: interfaces.ERROR_TOKEN_NOT_PASSED, + Message: "Invalid Token or token expired", + Name: "ERROR_TOKEN_NOT_PASSED", + } + } + return c.Next() +} + +func AllowOnlyValidLoggedInWhatsapp(c *fiber.Ctx) error { + jwtRawFromLocal := c.Locals(telegram_server_config.REQ_LOCAL_NUMBER_KEY) + token, ok := jwtRawFromLocal.(string) + if !ok { + return &interfaces.RequestError{ + StatusCode: 401, + Code: interfaces.ERROR_INVALID_TOKEN, + Message: "User Token Not Found", + Name: "ERROR_INVALID_TOKEN", + } + } + if value, ok := telegram_server_config.TelegramBotConfigMap.Tokens[token]; !ok { + return &interfaces.RequestError{ + StatusCode: 401, + Code: interfaces.ERROR_INVALID_TOKEN, + Message: "Invalid Token", + Name: "ERROR_INVALID_TOKEN", + } + } else if value == "" { + return &interfaces.RequestError{ + StatusCode: 401, + Code: interfaces.ERROR_CONNECTION_LOGGED_OUT, + Message: "Connection Not Connected Please Login to Whatsapp Account", + Name: "ERROR_CONNECTION_LOGGED_OUT", + } + } + return c.Next() +} diff --git a/servers/telegram-server/server.config.json_template b/servers/telegram-server/server.config.json_template new file mode 100644 index 0000000..0de2c8b --- /dev/null +++ b/servers/telegram-server/server.config.json_template @@ -0,0 +1,5 @@ +{ + "tokens": { + "XXXXXXAAAXXXXXXX":"91XXXXXXXXXX" + } +} \ No newline at end of file diff --git a/servers/telegram-server/telegram/function.go b/servers/telegram-server/telegram/function.go new file mode 100644 index 0000000..f445440 --- /dev/null +++ b/servers/telegram-server/telegram/function.go @@ -0,0 +1,31 @@ +package telegram_server + +import ( + "net/http" + + "github.com/gofiber/fiber/v2" + "github.com/rpsoftech/golang-servers/interfaces" + telegram_server_config "github.com/rpsoftech/golang-servers/servers/telegram-server/config" +) + +func ExtractNumberFromCtx(c *fiber.Ctx) (string, error) { + id, ok := c.Locals(telegram_server_config.REQ_LOCAL_NUMBER_KEY).(string) + if !ok { + return "", &interfaces.RequestError{ + StatusCode: http.StatusForbidden, + Code: interfaces.INVALID_NUMBER_FROM_TOKEN, + Message: "Invalid Number From Token", + Name: "INVALID_NUMBER_FROM_TOKEN", + } + } + return id, nil +} + +func ExtractKeyFromHeader(c *fiber.Ctx, key string) string { + reqHeaders := c.GetReqHeaders() + if tokenString, foundToken := reqHeaders[key]; !foundToken || len(tokenString) != 1 || tokenString[0] == "" { + return "" + } else { + return tokenString[0] + } +} diff --git a/servers/telegram-server/telegram/index.go b/servers/telegram-server/telegram/index.go new file mode 100644 index 0000000..07badd3 --- /dev/null +++ b/servers/telegram-server/telegram/index.go @@ -0,0 +1,52 @@ +package telegram_server + +import ( + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/rpsoftech/golang-servers/telegram" +) + +type ( + TelegramBotConnection struct { + BotToken string + bot *telegram.TelegramBot + } + ITelegramBotConnectionMap map[string]*TelegramBotConnection +) + +var ( + OutPutFilePath = "" + ConnectionMap *ITelegramBotConnectionMap +) + +func init() { + ConnectionMap = &ITelegramBotConnectionMap{} +} + +func (bot *TelegramBotConnection) SendMessage(chatId []int64, message string) *map[int64]*tgbotapi.Message { + result := make(map[int64]*tgbotapi.Message) + for _, id := range chatId { + if re, err := bot.bot.SendMessage(id, message); err == nil { + result[id] = &re + } else { + result[id] = nil + } + } + return &result +} + +func (cm ITelegramBotConnectionMap) GetBotConnection(token string) *TelegramBotConnection { + conn, found := cm[token] + if !found { + return nil + } + return conn +} +func (cm ITelegramBotConnectionMap) AddBotConnection(token string, connection *TelegramBotConnection) { + cm[token] = connection +} +func CreateTelegramBot(token string, bot *telegram.TelegramBot) *TelegramBotConnection { + return &TelegramBotConnection{ + BotToken: token, + bot: bot, + } +} diff --git a/servers/whatsapp-server/src/whatsapp/interfaces.go b/servers/whatsapp-server/src/whatsapp/interfaces.go index 4c5607e..4d3c9f7 100644 --- a/servers/whatsapp-server/src/whatsapp/interfaces.go +++ b/servers/whatsapp-server/src/whatsapp/interfaces.go @@ -40,7 +40,8 @@ var ( ) func (connection *WhatsappConnection) ReturnStatusError() error { - if connection.ConnectionStatus == 0 { + switch connection.ConnectionStatus { + case 0: return &interfaces.RequestError{ StatusCode: http.StatusNotFound, Code: interfaces.ERROR_CONNECTION_NOT_INITIALIZED, @@ -48,7 +49,7 @@ func (connection *WhatsappConnection) ReturnStatusError() error { Name: "ERROR_CONNECTION_NOT_INITIALIZED", Extra: []string{connection.QrCodeString}, } - } else if connection.ConnectionStatus == -1 { + case -1: return &interfaces.RequestError{ StatusCode: http.StatusNotFound, Code: interfaces.ERROR_CONNECTION_LOGGED_OUT, diff --git a/telegram/index.go b/telegram/index.go new file mode 100644 index 0000000..aaf5032 --- /dev/null +++ b/telegram/index.go @@ -0,0 +1,65 @@ +package telegram + +import ( + "fmt" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/rpsoftech/golang-servers/env" +) + +const TELEGRAM_APITOKEN_ENV_KEY = "TELEGRAM_APITOKEN" + +type TelegramBot struct { + BotAPI *tgbotapi.BotAPI +} + +func InitAndReturnTelegramBOT(token string) *TelegramBot { + if token == "" { + token = env.Env.GetEnv(TELEGRAM_APITOKEN_ENV_KEY) + } + if token == "" { + panic("Telegram API Token is not set in environment variables") + } + bot, err := tgbotapi.NewBotAPI(token) + if err != nil { + panic(err) + } + // bot.Debug = true + + return &TelegramBot{ + BotAPI: bot, + } +} + +func (bot *TelegramBot) SendMessage(chatId int64, message string) (tgbotapi.Message, error) { + msg := tgbotapi.NewMessage(chatId, message) + return bot.BotAPI.Send(msg) +} + +func (bot *TelegramBot) UserIdListner() { + updateConfig := tgbotapi.NewUpdate(0) + + // Tell Telegram we should wait up to 30 seconds on each request for an + // update. This way we can get information just as quickly as making many + // frequent requests without having to send nearly as many. + updateConfig.Timeout = 30 + updates := bot.BotAPI.GetUpdatesChan(updateConfig) + + // Let's go through each update that we're getting from Telegram. + for update := range updates { + if update.Message == nil { // ignore non-Message updates + continue + } + msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text) + switch update.Message.Command() { + case "userid": + msg.Text = fmt.Sprintf("Your User ID is: %d", update.Message.From.ID) + default: + msg.Text = "I don't know that command \n :( \n\n Please Use This Command /userid to get your User ID" + } + + if _, err := bot.BotAPI.Send(msg); err != nil { + fmt.Printf("%v", err) + } + } +} diff --git a/test.go b/test.go index 486d07c..459d4fe 100644 --- a/test.go +++ b/test.go @@ -2,11 +2,14 @@ package main import ( "fmt" - "path/filepath" + "strconv" ) func main() { - file_path := "/path/to/myfile.txt" //assign the absolute path - file_name := filepath.Base(file_path) //use this built-in function to obtain filename - fmt.Println(" The file Name from the absolute path is:", file_name) + num64 := int64(12345) + str := strconv.FormatInt(num64, 10) // Decimal string + hexStr := strconv.FormatInt(num64, 16) // Hexadecimal string + + fmt.Println("Decimal string:", str) + fmt.Println("Hexadecimal string:", hexStr) }