186 lines
4.6 KiB
Go

package streamer
import (
"bytes"
"donat-widget/internal/model"
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"strings"
)
func New(host, port string) *ClientStreamer {
return &ClientStreamer{
client: &http.Client{},
baseURL: "http://" + host + ":" + port + "/api/streamer",
}
}
type ClientStreamer struct {
client *http.Client
baseURL string
}
func (c *ClientStreamer) UpdateAvatarID(token string, avatarUUID string) error {
const endpoint = "/avatar"
// Подготовка тела запроса
requestBody := model.UpdateAvatarBody{
Avatar: avatarUUID,
}
jsonBody, err := json.Marshal(requestBody)
if err != nil {
slog.Error("marshal request body failed", "error", err)
return fmt.Errorf("request body marshal error: %w", err)
}
req, err := http.NewRequest(
"PATCH",
c.baseURL+endpoint,
bytes.NewBuffer(jsonBody),
)
if err != nil {
slog.Error("create request failed", "error", err)
return fmt.Errorf("request creation error: %w", err)
}
// Установка заголовков
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := c.client.Do(req)
if err != nil {
slog.Error("request failed", "error", err)
return fmt.Errorf("HTTP request error: %w", err)
}
defer resp.Body.Close()
// Проверка статус-кода
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
slog.Error("unexpected status code",
"status", resp.Status,
"response", string(body))
return fmt.Errorf("HTTP %d: %s", resp.StatusCode, resp.Status)
}
return nil
}
func (c *ClientStreamer) GetAvatarID(token string) (string, error) {
const endpoint = "/info"
var result model.StreamerInfo
req, err := http.NewRequest("GET", c.baseURL+endpoint, nil)
if err != nil {
slog.Error("create request failed", "error", err)
return "", fmt.Errorf("request creation error: %w", err)
}
req.Header.Set("Authorization", token)
req.Header.Set("Accept", "application/json")
resp, err := c.client.Do(req)
if err != nil {
slog.Error("request failed", "error", err)
return "", fmt.Errorf("HTTP request error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
slog.Error("unexpected status code",
"status", resp.Status,
"response", string(body))
return "", fmt.Errorf("HTTP %d: %s", resp.StatusCode, resp.Status)
}
rawBody, err := io.ReadAll(resp.Body)
if err != nil {
slog.Error("read body failed", "error", err)
return "", fmt.Errorf("read body error: %w", err)
}
if err := json.Unmarshal(rawBody, &result); err != nil {
slog.Error("JSON parse error",
"error", err,
"response", string(rawBody))
return "", fmt.Errorf("JSON unmarshal error: %w", err)
}
return extractFileID(result.Avatar), nil
}
// extractFileID извлекает последний сегмент URL (fileId)
func extractFileID(avatarURL string) string {
if avatarURL == "" {
return ""
}
// Удаляем возможный завершающий слэш
avatarURL = strings.TrimSuffix(avatarURL, "/")
// Разделяем URL по слэшам
parts := strings.Split(avatarURL, "/")
if len(parts) == 0 {
return ""
}
// Берём последнюю часть
return parts[len(parts)-1]
}
func (c *ClientStreamer) post(
path string,
body map[string]any,
token string,
) ([]byte, error) {
bytesBody, err := json.Marshal(body)
if err != nil {
slog.Error("json.Marshal error", "error", err)
return nil, fmt.Errorf("marshal error: %w", err)
}
// Создаем новый запрос
req, err := http.NewRequest(
"POST",
c.baseURL+path,
bytes.NewReader(bytesBody),
)
if err != nil {
slog.Error("request creation failed", "error", err)
return nil, fmt.Errorf("request error: %w", err)
}
req.Header.Set("Content-Type", "application/json")
if token != "" {
req.Header.Set("Authorization", "Bearer "+token)
}
resp, err := c.client.Do(req)
if err != nil {
slog.Error("request failed", "error", err)
return nil, fmt.Errorf("HTTP error: %w", err)
}
defer resp.Body.Close()
// Проверяем статус
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body) // Попробуем прочитать тело ошибки
slog.Error("unexpected status",
"status", resp.Status,
"body", string(body))
return nil, fmt.Errorf("status %d: %s", resp.StatusCode, resp.Status)
}
// Читаем ответ
response, err := io.ReadAll(resp.Body)
if err != nil {
slog.Error("read body failed", "error", err)
return nil, fmt.Errorf("read error: %w", err)
}
return response, nil
}