initial commit
This commit is contained in:
184
internal/infrastructure/packages/api_client.go
Normal file
184
internal/infrastructure/packages/api_client.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package packages
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/paramah/ai_devs4/s01e03/internal/domain"
|
||||
)
|
||||
|
||||
// APIClient implements domain.PackageClient
|
||||
type APIClient struct {
|
||||
baseURL string
|
||||
apiKey string
|
||||
client *http.Client
|
||||
verbose bool
|
||||
}
|
||||
|
||||
// NewAPIClient creates a new package API client
|
||||
func NewAPIClient(baseURL, apiKey string, verbose bool) *APIClient {
|
||||
return &APIClient{
|
||||
baseURL: baseURL,
|
||||
apiKey: apiKey,
|
||||
client: &http.Client{},
|
||||
verbose: verbose,
|
||||
}
|
||||
}
|
||||
|
||||
type checkRequest struct {
|
||||
APIKey string `json:"apikey"`
|
||||
Action string `json:"action"`
|
||||
PackageID string `json:"packageid"`
|
||||
}
|
||||
|
||||
type checkResponse struct {
|
||||
Status string `json:"status"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type redirectRequest struct {
|
||||
APIKey string `json:"apikey"`
|
||||
Action string `json:"action"`
|
||||
PackageID string `json:"packageid"`
|
||||
Destination string `json:"destination"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type redirectResponse struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Confirmation string `json:"confirmation,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Check checks the status of a package
|
||||
func (c *APIClient) Check(ctx context.Context, packageID string) (*domain.PackageStatus, error) {
|
||||
reqBody := checkRequest{
|
||||
APIKey: c.apiKey,
|
||||
Action: "check",
|
||||
PackageID: packageID,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshaling request: %w", err)
|
||||
}
|
||||
|
||||
if c.verbose {
|
||||
var prettyJSON bytes.Buffer
|
||||
if err := json.Indent(&prettyJSON, jsonData, "", " "); err == nil {
|
||||
log.Printf("\n========== PACKAGE API CHECK REQUEST ==========\nURL: %s\nBody:\n%s\n===============================================\n", c.baseURL, prettyJSON.String())
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sending request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading response: %w", err)
|
||||
}
|
||||
|
||||
if c.verbose {
|
||||
var prettyJSON bytes.Buffer
|
||||
if err := json.Indent(&prettyJSON, body, "", " "); err == nil {
|
||||
log.Printf("\n========== PACKAGE API CHECK RESPONSE ==========\nStatus: %d\nBody:\n%s\n================================================\n", resp.StatusCode, prettyJSON.String())
|
||||
}
|
||||
}
|
||||
|
||||
var apiResp checkResponse
|
||||
if err := json.Unmarshal(body, &apiResp); err != nil {
|
||||
return nil, fmt.Errorf("unmarshaling response: %w", err)
|
||||
}
|
||||
|
||||
if apiResp.Error != "" {
|
||||
return nil, fmt.Errorf("API error: %s", apiResp.Error)
|
||||
}
|
||||
|
||||
return &domain.PackageStatus{
|
||||
PackageID: packageID,
|
||||
Status: apiResp.Status,
|
||||
Location: apiResp.Location,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Redirect redirects a package to a new destination and returns the confirmation message
|
||||
func (c *APIClient) Redirect(ctx context.Context, packageID, destination, code string) (string, error) {
|
||||
reqBody := redirectRequest{
|
||||
APIKey: c.apiKey,
|
||||
Action: "redirect",
|
||||
PackageID: packageID,
|
||||
Destination: destination,
|
||||
Code: code,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("marshaling request: %w", err)
|
||||
}
|
||||
|
||||
if c.verbose {
|
||||
var prettyJSON bytes.Buffer
|
||||
if err := json.Indent(&prettyJSON, jsonData, "", " "); err == nil {
|
||||
log.Printf("\n========== PACKAGE API REDIRECT REQUEST ==========\nURL: %s\nBody:\n%s\n==================================================\n", c.baseURL, prettyJSON.String())
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sending request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading response: %w", err)
|
||||
}
|
||||
|
||||
if c.verbose {
|
||||
var prettyJSON bytes.Buffer
|
||||
if err := json.Indent(&prettyJSON, body, "", " "); err == nil {
|
||||
log.Printf("\n========== PACKAGE API REDIRECT RESPONSE ==========\nStatus: %d\nBody:\n%s\n===================================================\n", resp.StatusCode, prettyJSON.String())
|
||||
}
|
||||
}
|
||||
|
||||
var apiResp redirectResponse
|
||||
if err := json.Unmarshal(body, &apiResp); err != nil {
|
||||
return "", fmt.Errorf("unmarshaling response: %w", err)
|
||||
}
|
||||
|
||||
if apiResp.Error != "" {
|
||||
return "", fmt.Errorf("API error: %s", apiResp.Error)
|
||||
}
|
||||
|
||||
// Return the confirmation code
|
||||
if apiResp.Confirmation != "" {
|
||||
return apiResp.Confirmation, nil
|
||||
}
|
||||
|
||||
// Fallback to message if confirmation is not present
|
||||
return apiResp.Message, nil
|
||||
}
|
||||
Reference in New Issue
Block a user