+notification from site +version bump fix
Some checks failed
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/bump_version Pipeline failed
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
Some checks failed
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/bump_version Pipeline failed
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
notconfig "github.com/tech/sendico/notification/interface/services/notification/config"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
)
|
||||
|
||||
const defaultAPIURL = "https://api.telegram.org"
|
||||
|
||||
type Client interface {
|
||||
SendDemoRequest(ctx context.Context, request *model.DemoRequest) error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
logger mlogger.Logger
|
||||
httpClient *http.Client
|
||||
apiURL string
|
||||
botToken string
|
||||
chatID string
|
||||
threadID *int64
|
||||
parseMode string
|
||||
}
|
||||
|
||||
type sendMessagePayload struct {
|
||||
ChatID string `json:"chat_id"`
|
||||
Text string `json:"text"`
|
||||
ParseMode string `json:"parse_mode,omitempty"`
|
||||
ThreadID *int64 `json:"message_thread_id,omitempty"`
|
||||
DisablePreview bool `json:"disable_web_page_preview,omitempty"`
|
||||
DisableNotify bool `json:"disable_notification,omitempty"`
|
||||
ProtectContent bool `json:"protect_content,omitempty"`
|
||||
}
|
||||
|
||||
func NewClient(logger mlogger.Logger, cfg *notconfig.TelegramConfig) (Client, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("telegram configuration is not provided")
|
||||
}
|
||||
token := strings.TrimSpace(os.Getenv(cfg.BotTokenEnv))
|
||||
if token == "" {
|
||||
return nil, fmt.Errorf("telegram bot token env %s is empty", cfg.BotTokenEnv)
|
||||
}
|
||||
chatID := strings.TrimSpace(os.Getenv(cfg.ChatIDEnv))
|
||||
if chatID == "" {
|
||||
return nil, fmt.Errorf("telegram chat id env %s is empty", cfg.ChatIDEnv)
|
||||
}
|
||||
|
||||
var threadID *int64
|
||||
if env := strings.TrimSpace(cfg.ThreadIDEnv); env != "" {
|
||||
raw := strings.TrimSpace(os.Getenv(env))
|
||||
if raw != "" {
|
||||
val, err := strconv.ParseInt(raw, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("telegram thread id env %s is invalid: %w", env, err)
|
||||
}
|
||||
threadID = &val
|
||||
}
|
||||
}
|
||||
|
||||
timeout := time.Duration(cfg.TimeoutSeconds) * time.Second
|
||||
if timeout <= 0 {
|
||||
timeout = 10 * time.Second
|
||||
}
|
||||
|
||||
apiURL := strings.TrimSpace(cfg.APIURL)
|
||||
if apiURL == "" {
|
||||
apiURL = defaultAPIURL
|
||||
}
|
||||
|
||||
return &client{
|
||||
logger: logger.Named("telegram"),
|
||||
httpClient: &http.Client{
|
||||
Timeout: timeout,
|
||||
},
|
||||
apiURL: strings.TrimRight(apiURL, "/"),
|
||||
botToken: token,
|
||||
chatID: chatID,
|
||||
threadID: threadID,
|
||||
parseMode: strings.TrimSpace(cfg.ParseMode),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *client) SendDemoRequest(ctx context.Context, request *model.DemoRequest) error {
|
||||
if request == nil {
|
||||
return fmt.Errorf("demo request payload is nil")
|
||||
}
|
||||
message := buildMessage(request)
|
||||
payload := sendMessagePayload{
|
||||
ChatID: c.chatID,
|
||||
Text: message,
|
||||
ParseMode: c.parseMode,
|
||||
ThreadID: c.threadID,
|
||||
DisablePreview: true,
|
||||
}
|
||||
return c.sendMessage(ctx, payload)
|
||||
}
|
||||
|
||||
func (c *client) sendMessage(ctx context.Context, payload sendMessagePayload) error {
|
||||
body, err := json.Marshal(&payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.endpoint(), bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices {
|
||||
return nil
|
||||
}
|
||||
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
|
||||
return fmt.Errorf("telegram sendMessage failed with status %d: %s", resp.StatusCode, string(respBody))
|
||||
}
|
||||
|
||||
func (c *client) endpoint() string {
|
||||
return fmt.Sprintf("%s/bot%s/sendMessage", c.apiURL, c.botToken)
|
||||
}
|
||||
|
||||
func buildMessage(req *model.DemoRequest) string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("New demo request received\n")
|
||||
builder.WriteString(fmt.Sprintf("Name: %s\n", req.Name))
|
||||
builder.WriteString(fmt.Sprintf("Organization: %s\n", req.OrganizationName))
|
||||
builder.WriteString(fmt.Sprintf("Phone: %s\n", req.Phone))
|
||||
builder.WriteString(fmt.Sprintf("Work email: %s\n", req.WorkEmail))
|
||||
builder.WriteString(fmt.Sprintf("Payout volume: %s\n", req.PayoutVolume))
|
||||
if req.Comment != "" {
|
||||
builder.WriteString(fmt.Sprintf("Comment: %s\n", req.Comment))
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
Reference in New Issue
Block a user