Cliente com cURL
<?php
class ShappireClient
{
public function __construct(
private readonly string $apiKey,
private readonly string $base = 'https://api.shappire.tools/v1',
) {}
public function resolve(string $url): array
{
return $this->request('POST', '/media/resolve', ['url' => $url]);
}
public function enqueue(string $mediaId, string $format): string
{
$data = $this->request('POST', '/media/download', [
'media_id' => $mediaId,
'format' => $format,
]);
return $data['job_id'];
}
public function getJob(string $jobId): array
{
return $this->request('GET', "/jobs/{$jobId}");
}
private function request(string $method, string $path, ?array $body = null): array
{
$ch = curl_init($this->base . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: {$this->apiKey}",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$json = json_decode($response, true);
if ($status >= 400) {
throw new RuntimeException($json['error']['message'] ?? 'request failed');
}
return $json['data'];
}
}
Com Guzzle
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api.shappire.tools/v1/',
'headers' => ['X-API-Key' => env('SHAPPIRE_API_KEY')],
]);
$media = json_decode(
$client->post('media/resolve', ['json' => ['url' => $url]])->getBody(),
true
)['data'];
Laravel — Job assíncrono
class DownloadMediaJob implements ShouldQueue
{
public function __construct(public string $url) {}
public function handle(): void
{
$client = new ShappireClient(config('services.shappire.key'));
$media = $client->resolve($this->url);
$jobId = $client->enqueue($media['id'], 'video_best');
do {
sleep(3);
$job = $client->getJob($jobId);
} while (!in_array($job['status'], ['completed', 'failed'], true));
Storage::putFileFromUrl('downloads/'.$job['result']['filename'], $job['result']['download_url']);
}
}