Spaces:
Runtime error
Runtime error
File size: 5,564 Bytes
46252cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | <?php
declare(strict_types=1);
namespace OpenWA;
use GuzzleHttp\ClientInterface;
use OpenWA\Exceptions\OpenWAException;
use OpenWA\Http\HttpExecutor;
use OpenWA\Resources\CatalogResource;
use OpenWA\Resources\CallsResource;
use OpenWA\Resources\ChannelsResource;
use OpenWA\Resources\ChatsResource;
use OpenWA\Resources\ContactsResource;
use OpenWA\Resources\GroupsResource;
use OpenWA\Resources\HealthResource;
use OpenWA\Resources\LabelsResource;
use OpenWA\Resources\MessagesResource;
use OpenWA\Resources\ProfileResource;
use OpenWA\Resources\SearchResource;
use OpenWA\Resources\SessionsResource;
use OpenWA\Resources\StatusResource;
use OpenWA\Resources\TemplatesResource;
use OpenWA\Resources\WebhooksResource;
/**
* OpenWA PHP SDK — client core.
*
* The single entry point. It owns an {@see HttpExecutor} (which wraps a Guzzle
* client with an injectable handler) and exposes domain resources as
* properties:
*
* ```php
* use OpenWA\Client;
*
* $client = new Client([
* 'baseUrl' => 'http://localhost:2785',
* 'apiKey' => 'owa_k1_…',
* ]);
*
* $client->sessions->start('my-session');
* $result = $client->messages->sendText('my-session', [
* 'chatId' => '628123456789@c.us',
* 'text' => 'Hello from the OpenWA PHP SDK!',
* ]);
* echo $result['messageId'];
* ```
*
* For testing, inject a Guzzle client whose handler is a MockHandler.
*/
class Client
{
private HttpExecutor $http;
public SessionsResource $sessions;
public MessagesResource $messages;
public SearchResource $search;
public ContactsResource $contacts;
public GroupsResource $groups;
public WebhooksResource $webhooks;
public ChatsResource $chats;
public StatusResource $status;
public HealthResource $health;
public LabelsResource $labels;
public ChannelsResource $channels;
public CatalogResource $catalog;
public TemplatesResource $templates;
public ProfileResource $profile;
public CallsResource $calls;
/**
* @param array{
* baseUrl:string,
* apiKey:string,
* timeout?:float,
* httpClient?:?\GuzzleHttp\ClientInterface|null,
* defaultHeaders?:array<string,string>
* } $config
*
* @throws OpenWAException If baseUrl or apiKey is missing.
*/
public function __construct(array $config)
{
if (empty($config['baseUrl'])) {
throw new OpenWAException('OpenWA Client: baseUrl is required');
}
if (empty($config['apiKey'])) {
throw new OpenWAException('OpenWA Client: apiKey is required');
}
self::warnIfInsecureHttp($config['baseUrl']);
$this->http = new HttpExecutor(
$config['baseUrl'],
$config['apiKey'],
$config['timeout'] ?? 30.0,
$config['httpClient'] ?? null,
$config['defaultHeaders'] ?? [],
);
$this->sessions = new SessionsResource($this->http);
$this->messages = new MessagesResource($this->http);
$this->search = new SearchResource($this->http);
$this->contacts = new ContactsResource($this->http);
$this->groups = new GroupsResource($this->http);
$this->webhooks = new WebhooksResource($this->http);
$this->chats = new ChatsResource($this->http);
$this->status = new StatusResource($this->http);
$this->health = new HealthResource($this->http);
$this->labels = new LabelsResource($this->http);
$this->channels = new ChannelsResource($this->http);
$this->catalog = new CatalogResource($this->http);
$this->templates = new TemplatesResource($this->http);
$this->profile = new ProfileResource($this->http);
$this->calls = new CallsResource($this->http);
}
/**
* Warn (not throw) when baseUrl is http:// and the host is not localhost. The API key is sent
* as an X-API-Key header on every request — over plaintext http to a non-local host that's
* cleartext on the wire. Warning (not refusing) keeps local dev and TLS-terminating-proxy
* topologies working.
*/
private static function warnIfInsecureHttp(string $url): void
{
$scheme = \parse_url($url, \PHP_URL_SCHEME);
$host = \parse_url($url, \PHP_URL_HOST);
if ($scheme === 'http' && $host !== null && $host !== false) {
$host = \trim($host, '[]');
if (!\in_array($host, ['localhost', '127.0.0.1', '::1'], true)) {
\trigger_error(
"OpenWA Client: baseUrl uses an insecure http:// URL (host: {$host}). "
. 'The API key will be sent in cleartext. Use https:// in production.',
\E_USER_WARNING
);
}
}
}
/** Validate the configured API key and resolve its role. */
public function auth(): array
{
return $this->http->request('POST', '/api/auth/validate') ?? [];
}
/**
* Issue a raw request against the API (advanced use).
*
* @param string $path Path beginning with /, e.g. /api/sessions.
* @param array<string,mixed> $query Query parameters (null values skipped).
* @param mixed|null $body JSON-serializable request body.
* @return mixed Decoded JSON, or null for empty/204 responses.
*/
public function request(string $method, string $path, array $query = [], mixed $body = null): mixed
{
return $this->http->request($method, $path, $query, $body);
}
}
|