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) GetAvatarIdByToken(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 } func (c *ClientStreamer) GetAvatarById(accountId string) (string, error) { var endpoint = "/info" + "/" + accountId 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("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 }