186 lines
4.6 KiB
Go
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", 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
|
|
}
|