Qo'shildi: Docker konfiguratsiyasi yangilandi, .env va .gitignore fayllari yaratildi, Redis va muhit o'zgaruvchilari qo'shildi.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package consumer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -11,10 +12,14 @@ import (
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
type notificationConsumer struct{}
|
||||
type notificationConsumer struct {
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
func NewNotificationConsumer() domain.NotificationConsumerPort {
|
||||
return ¬ificationConsumer{}
|
||||
func NewNotificationConsumer(ctx context.Context) domain.NotificationConsumerPort {
|
||||
return ¬ificationConsumer{
|
||||
Ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (n *notificationConsumer) Start() {
|
||||
@@ -54,7 +59,7 @@ func (n *notificationConsumer) Handler(msg amqp.Delivery) {
|
||||
var ntf domain.NotifierPort
|
||||
switch notification.Type {
|
||||
case "sms":
|
||||
ntf = notifier.NewSmsNotifier()
|
||||
ntf = notifier.NewSmsNotifier(n.Ctx)
|
||||
case "email":
|
||||
ntf = notifier.NewEmailNotifier()
|
||||
}
|
||||
|
||||
27
internal/domain/eskiz.go
Normal file
27
internal/domain/eskiz.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package domain
|
||||
|
||||
type EskizLogin struct {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type EskizLoginRes struct {
|
||||
Message string
|
||||
TokenType string
|
||||
Data struct {
|
||||
Token string
|
||||
}
|
||||
}
|
||||
|
||||
type EskizMessage struct {
|
||||
Phone string `json:"mobile_phone"`
|
||||
Message string `json:"message"`
|
||||
From string `json:"from"`
|
||||
CallbackURL string `json:"callback_url"`
|
||||
}
|
||||
|
||||
type EskizMessageRes struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
@@ -7,6 +7,9 @@ type NotificationConsumerPort interface {
|
||||
Handler(amqp.Delivery)
|
||||
}
|
||||
|
||||
type SMSServicePort interface {
|
||||
SendSMS(string, string) error
|
||||
}
|
||||
type NotifierPort interface {
|
||||
SendMessage([]string, string)
|
||||
}
|
||||
|
||||
20
internal/domain/playmobile.go
Normal file
20
internal/domain/playmobile.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package domain
|
||||
|
||||
type PmbContent struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type PmbSMS struct {
|
||||
Originator string `json:"originator"`
|
||||
Content PmbContent `json:"content"`
|
||||
}
|
||||
|
||||
type PmbMessage struct {
|
||||
Recipient string `json:"recipient"`
|
||||
MessageID string `json:"message-id"`
|
||||
Sms PmbSMS `json:"sms"`
|
||||
}
|
||||
|
||||
type PmbPayload struct {
|
||||
Messages []PmbMessage
|
||||
}
|
||||
@@ -1,16 +1,25 @@
|
||||
package notifier
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JscorpTech/notification/internal/domain"
|
||||
"github.com/k0kubun/pp/v3"
|
||||
"github.com/JscorpTech/notification/internal/services"
|
||||
)
|
||||
|
||||
type smsNotifier struct{}
|
||||
type smsNotifier struct {
|
||||
SMSServie domain.SMSServicePort
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
func NewSmsNotifier() domain.NotifierPort {
|
||||
return &smsNotifier{}
|
||||
func NewSmsNotifier(ctx context.Context) domain.NotifierPort {
|
||||
return &smsNotifier{
|
||||
SMSServie: services.NewEskizSMSService(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *smsNotifier) SendMessage(to []string, body string) {
|
||||
pp.Print(to, body)
|
||||
for _, user := range to {
|
||||
n.SMSServie.SendSMS(user, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ package rabbitmq
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
func Connect() (*amqp.Connection, *amqp.Channel, error) {
|
||||
conn, err := amqp.Dial("amqp://guest:guest@rabbitmq:5672/")
|
||||
conn, err := amqp.Dial(os.Getenv("RABBITMQ_URL"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
27
internal/redis/client.go
Normal file
27
internal/redis/client.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
var RDB *redis.Client
|
||||
|
||||
func InitRedis() {
|
||||
DB, _ := strconv.Atoi(os.Getenv("REDIS_DB"))
|
||||
RDB = redis.NewClient(&redis.Options{
|
||||
Addr: os.Getenv("REDIS_ADDRESS"),
|
||||
Password: os.Getenv("REDIS_PASSWORD"),
|
||||
DB: DB,
|
||||
})
|
||||
|
||||
// Test connection
|
||||
_, err := RDB.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
log.Fatalf("Redisga ulanib bo'lmadi: %v", err)
|
||||
}
|
||||
}
|
||||
89
internal/services/eskiz.go
Normal file
89
internal/services/eskiz.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/JscorpTech/notification/internal/domain"
|
||||
"github.com/JscorpTech/notification/internal/redis"
|
||||
"github.com/k0kubun/pp/v3"
|
||||
)
|
||||
|
||||
type eskizSMSService struct {
|
||||
BaseURL string
|
||||
Ctx context.Context
|
||||
}
|
||||
|
||||
// /broker-api/send
|
||||
func NewEskizSMSService(ctx context.Context) domain.SMSServicePort {
|
||||
return &eskizSMSService{
|
||||
Ctx: ctx,
|
||||
BaseURL: os.Getenv("ESKIZ_DOMAIN"),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *eskizSMSService) Request(payload any, path string, isAuth bool, retry bool) (*http.Response, error) {
|
||||
var buf bytes.Buffer
|
||||
_ = json.NewEncoder(&buf).Encode(payload)
|
||||
client := http.Client{
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
req, err := http.NewRequest("POST", e.BaseURL+path, &buf)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
if isAuth {
|
||||
req.Header.Add("Authorization", "Bearer "+e.GetToken(true))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if res.StatusCode == http.StatusUnauthorized && retry {
|
||||
pp.Print("Qayta urunish")
|
||||
e.GetToken(false)
|
||||
return e.Request(payload, path, isAuth, false)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (e *eskizSMSService) GetToken(cache bool) string {
|
||||
token, err := redis.RDB.Get(e.Ctx, "eskiz_token").Result()
|
||||
if err == nil && cache {
|
||||
pp.Print("Eskiz token topildi 😁")
|
||||
return token
|
||||
}
|
||||
payload := domain.EskizLogin{
|
||||
Email: os.Getenv("ESKIZ_USER"),
|
||||
Password: os.Getenv("ESKIZ_PASSWORD"),
|
||||
}
|
||||
res, err := e.Request(payload, "/auth/login", false, true)
|
||||
if err != nil {
|
||||
pp.Print(err.Error())
|
||||
}
|
||||
var data domain.EskizLoginRes
|
||||
_ = json.NewDecoder(res.Body).Decode(&data)
|
||||
token = data.Data.Token
|
||||
redis.RDB.Set(e.Ctx, "eskiz_token", token, 30*24*time.Hour)
|
||||
pp.Print("Eskiz yangi token olindi 😔")
|
||||
return token
|
||||
}
|
||||
|
||||
func (e *eskizSMSService) SendSMS(to, body string) error {
|
||||
payload := domain.EskizMessage{
|
||||
Phone: to,
|
||||
Message: body,
|
||||
From: os.Getenv("ESKIZ_FROM"),
|
||||
}
|
||||
res, err := e.Request(payload, "/message/sms/send", true, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var data domain.EskizMessageRes
|
||||
json.NewDecoder(res.Body).Decode(&data)
|
||||
pp.Print(data)
|
||||
return nil
|
||||
}
|
||||
53
internal/services/playmobile.go
Normal file
53
internal/services/playmobile.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/JscorpTech/notification/internal/domain"
|
||||
)
|
||||
|
||||
type pmbSMSService struct {
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
// /broker-api/send
|
||||
func NewPmbSMSService() domain.SMSServicePort {
|
||||
return &pmbSMSService{
|
||||
BaseURL: "https://send.smsxabar.uz",
|
||||
}
|
||||
}
|
||||
|
||||
func (e *pmbSMSService) SendSMS(to, body string) error {
|
||||
client := http.Client{
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
payload := domain.PmbPayload{
|
||||
Messages: []domain.PmbMessage{
|
||||
{
|
||||
Recipient: "+998888112309",
|
||||
MessageID: "salomsdfs",
|
||||
Sms: domain.PmbSMS{
|
||||
Originator: "3600",
|
||||
Content: domain.PmbContent{
|
||||
Text: "salom",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_ = json.NewEncoder(&buf).Encode(payload)
|
||||
req, _ := http.NewRequest("POST", e.BaseURL+"/broker-api/send", &buf)
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var data map[string]interface{}
|
||||
json.NewDecoder(res.Body).Decode(&data)
|
||||
fmt.Print(data)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user