Delete notification service
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
RABBITMQ_URL=amqp://guest:guest@127.0.0.1:5672/
|
|
||||||
|
|
||||||
|
|
||||||
REDIS_ADDRESS=127.0.0.1:6379
|
|
||||||
REDIS_PASSWORD=
|
|
||||||
REDIS_DB=0
|
|
||||||
|
|
||||||
ESKIZ_DOMAIN="https://notify.eskiz.uz/api"
|
|
||||||
ESKIZ_USER="admin@gmail.com"
|
|
||||||
ESKIZ_PASSWORD="password"
|
|
||||||
ESKIZ_FROM="4546"
|
|
||||||
|
|
||||||
PMB_DOMAIN=""
|
|
||||||
PMB_USER=""
|
|
||||||
PMB_PASSWORD=""
|
|
||||||
3
notification/.gitignore
vendored
3
notification/.gitignore
vendored
@@ -1,3 +0,0 @@
|
|||||||
.env
|
|
||||||
./bin
|
|
||||||
./main
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
FROM golang:alpine AS build
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN go build -o notification ./cmd/main.go
|
|
||||||
|
|
||||||
FROM alpine
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY --from=build /app/notification .
|
|
||||||
COPY ./.env /app/
|
|
||||||
|
|
||||||
CMD ["./notification"]
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
# Notification Service
|
|
||||||
|
|
||||||
A microservice for handling and delivering notifications through various channels like SMS and email using RabbitMQ as a message broker.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This notification service is designed as a standalone microservice that consumes notification requests from a RabbitMQ queue and routes them to the appropriate notification provider based on the notification type. Currently, it supports SMS and email notifications.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Message consumption from RabbitMQ
|
|
||||||
- Support for multiple notification channels (SMS, email)
|
|
||||||
- Extensible architecture for adding new notification types
|
|
||||||
- Asynchronous notification handling
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
The notification service follows a clean architecture approach:
|
|
||||||
|
|
||||||
- **Domain Layer**: Contains core business logic and port interfaces
|
|
||||||
- **Infrastructure Layer**: Implements the ports with concrete adapters
|
|
||||||
- **RabbitMQ**: Used as a message broker for consuming notification requests
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- Go 1.x+
|
|
||||||
- RabbitMQ server
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
1. Clone the repository:
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/JscorpTech/notification.git
|
|
||||||
cd notification
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install dependencies:
|
|
||||||
```bash
|
|
||||||
go mod download
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Build the application:
|
|
||||||
```bash
|
|
||||||
go build -o notification-service
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Configure your RabbitMQ connection and other settings in the appropriate configuration files.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Running the service
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./notification-service
|
|
||||||
```
|
|
||||||
|
|
||||||
This will start the notification consumer that listens for incoming notification requests.
|
|
||||||
|
|
||||||
### Sending a notification
|
|
||||||
|
|
||||||
Notifications should be published to the RabbitMQ exchange with the following JSON format:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "email",
|
|
||||||
"message": "Hello, this is a test notification.",
|
|
||||||
"to": ["user@example.com"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Python example
|
|
||||||
```python
|
|
||||||
from kombu import Connection, Exchange, Producer
|
|
||||||
|
|
||||||
# RabbitMQ ulanishi
|
|
||||||
rabbit_url = 'amqp://guest:guest@127.0.0.1:5672/'
|
|
||||||
connection = Connection(rabbit_url)
|
|
||||||
channel = connection.channel()
|
|
||||||
|
|
||||||
exchange = Exchange('notification', type='direct')
|
|
||||||
|
|
||||||
# Producer yaratish
|
|
||||||
producer = Producer(channel, exchange=exchange, routing_key="notification")
|
|
||||||
|
|
||||||
# Xabar yuborish
|
|
||||||
message = {'type': 'sms', 'message': "classcom.uz sayti va mobil ilovasiga ro'yxatdan o'tishingingiz uchun tasdiqlash kodi: 1234", "to": ["+998888112309", "+998943990509"]}
|
|
||||||
producer.publish(message)
|
|
||||||
|
|
||||||
print("Message sent to all workers!")
|
|
||||||
```
|
|
||||||
|
|
||||||
Available notification types:
|
|
||||||
- `email`: For email notifications
|
|
||||||
- `sms`: For SMS notifications
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
notification/
|
|
||||||
├── cmd/
|
|
||||||
│ └── main.go # Entry point
|
|
||||||
├── internal/
|
|
||||||
│ ├── domain/
|
|
||||||
│ │ └── ports.go # Interfaces
|
|
||||||
│ ├── notifier/
|
|
||||||
│ │ ├── email.go # Email notification implementation
|
|
||||||
│ │ └── sms.go # SMS notification implementation
|
|
||||||
│ ├── rabbitmq/
|
|
||||||
│ │ └── connection.go # RabbitMQ connection handling
|
|
||||||
│ └── consumer/
|
|
||||||
│ └── consumer.go # Implementation of the notification consumer
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create your feature branch: `git checkout -b feature/my-new-feature`
|
|
||||||
3. Commit your changes: `git commit -am 'Add some feature'`
|
|
||||||
4. Push to the branch: `git push origin feature/my-new-feature`
|
|
||||||
5. Submit a pull request
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[Add your license here]
|
|
||||||
|
|
||||||
## Contact
|
|
||||||
|
|
||||||
JscorpTech - [GitHub](https://github.com/JscorpTech)
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/JscorpTech/notification/internal/consumer"
|
|
||||||
"github.com/JscorpTech/notification/internal/redis"
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ctx = context.Background()
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := godotenv.Load(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
redis.InitRedis()
|
|
||||||
notification := consumer.NewNotificationConsumer(ctx)
|
|
||||||
notification.Start()
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
networks:
|
|
||||||
lamenu:
|
|
||||||
external: true
|
|
||||||
name: lamenu
|
|
||||||
|
|
||||||
services:
|
|
||||||
notification:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
networks:
|
|
||||||
- lamenu
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
module github.com/JscorpTech/notification
|
|
||||||
|
|
||||||
go 1.24.0
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
|
||||||
github.com/k0kubun/pp/v3 v3.4.1 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
|
||||||
github.com/redis/go-redis/v9 v9.7.3 // indirect
|
|
||||||
github.com/streadway/amqp v1.1.0 // indirect
|
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
|
||||||
golang.org/x/text v0.19.0 // indirect
|
|
||||||
)
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
|
||||||
github.com/k0kubun/pp/v3 v3.4.1 h1:1WdFZDRRqe8UsR61N/2RoOZ3ziTEqgTPVqKrHeb779Y=
|
|
||||||
github.com/k0kubun/pp/v3 v3.4.1/go.mod h1:+SiNiqKnBfw1Nkj82Lh5bIeKQOAkPy6Xw9CAZUZ8npI=
|
|
||||||
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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
|
||||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
|
||||||
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
|
|
||||||
github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM=
|
|
||||||
github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg=
|
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
|
||||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetEnv(key, fallback string) string {
|
|
||||||
val := os.Getenv(key)
|
|
||||||
if val == "" {
|
|
||||||
return fallback
|
|
||||||
}
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package consumer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/JscorpTech/notification/internal/domain"
|
|
||||||
"github.com/JscorpTech/notification/internal/notifier"
|
|
||||||
"github.com/JscorpTech/notification/internal/rabbitmq"
|
|
||||||
"github.com/streadway/amqp"
|
|
||||||
)
|
|
||||||
|
|
||||||
type notificationConsumer struct {
|
|
||||||
Ctx context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNotificationConsumer(ctx context.Context) domain.NotificationConsumerPort {
|
|
||||||
return ¬ificationConsumer{
|
|
||||||
Ctx: ctx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *notificationConsumer) Start() {
|
|
||||||
conn, ch, err := rabbitmq.Connect()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
defer ch.Close()
|
|
||||||
|
|
||||||
exchangeName := "notification"
|
|
||||||
queueName := "notification"
|
|
||||||
routingKey := "notification"
|
|
||||||
|
|
||||||
ch.ExchangeDeclare(exchangeName, "direct", true, false, false, false, nil)
|
|
||||||
q, _ := ch.QueueDeclare(queueName, true, false, false, false, nil)
|
|
||||||
ch.QueueBind(q.Name, routingKey, exchangeName, false, nil)
|
|
||||||
|
|
||||||
msgs, _ := ch.Consume(q.Name, "", true, false, false, false, nil)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for msg := range msgs {
|
|
||||||
go n.Handler(msg)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fmt.Println("🚀 Server started. Ctrl+C to quit.")
|
|
||||||
select {}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *notificationConsumer) Handler(msg amqp.Delivery) {
|
|
||||||
var notification domain.NotificationMsg
|
|
||||||
err := json.Unmarshal(msg.Body, ¬ification)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Print(err.Error())
|
|
||||||
}
|
|
||||||
var ntf domain.NotifierPort
|
|
||||||
switch notification.Type {
|
|
||||||
case "sms":
|
|
||||||
ntf = notifier.NewSmsNotifier(n.Ctx)
|
|
||||||
case "email":
|
|
||||||
ntf = notifier.NewEmailNotifier()
|
|
||||||
}
|
|
||||||
ntf.SendMessage(notification.To, notification.Message)
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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"`
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package domain
|
|
||||||
|
|
||||||
import "github.com/streadway/amqp"
|
|
||||||
|
|
||||||
type NotificationConsumerPort interface {
|
|
||||||
Start()
|
|
||||||
Handler(amqp.Delivery)
|
|
||||||
}
|
|
||||||
|
|
||||||
type SMSServicePort interface {
|
|
||||||
SendSMS(string, string) error
|
|
||||||
}
|
|
||||||
type NotifierPort interface {
|
|
||||||
SendMessage([]string, string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotificationMsg struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
To []string `json:"to"`
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
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 +0,0 @@
|
|||||||
package models
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package notifier
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/JscorpTech/notification/internal/domain"
|
|
||||||
"github.com/k0kubun/pp/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type emailNotifier struct{}
|
|
||||||
|
|
||||||
func NewEmailNotifier() domain.NotifierPort {
|
|
||||||
return &emailNotifier{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *emailNotifier) SendMessage(to []string, body string) {
|
|
||||||
pp.Print(to, body)
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package notifier
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/JscorpTech/notification/internal/domain"
|
|
||||||
"github.com/JscorpTech/notification/internal/services"
|
|
||||||
)
|
|
||||||
|
|
||||||
type smsNotifier struct {
|
|
||||||
SMSServie domain.SMSServicePort
|
|
||||||
Ctx context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSmsNotifier(ctx context.Context) domain.NotifierPort {
|
|
||||||
return &smsNotifier{
|
|
||||||
SMSServie: services.NewEskizSMSService(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *smsNotifier) SendMessage(to []string, body string) {
|
|
||||||
for _, user := range to {
|
|
||||||
n.SMSServie.SendSMS(user, body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package rabbitmq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/streadway/amqp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Connect() (*amqp.Connection, *amqp.Channel, error) {
|
|
||||||
conn, err := amqp.Dial(os.Getenv("RABBITMQ_URL"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
ch, err := conn.Channel()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
log.Println("🐇 Connected to RabbitMQ")
|
|
||||||
|
|
||||||
return conn, ch, nil
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
|
|
||||||
Reference in New Issue
Block a user