nickdnk / gatewayapi-php
基于Guzzle的PHP库,用于与gatewayapi.com集成
Requires
- php: ^7.1 || ^8.0
- ext-json: *
- guzzlehttp/guzzle: ^6.0 || ^7.0
- guzzlehttp/oauth-subscriber: 0.3.* || 0.4.* || 0.5.* || 0.6.*
Requires (Dev)
- php-coveralls/php-coveralls: ^v2.5.2
- phpunit/phpunit: ^7.0 || ^8.0 || ^9.0
README
GatewayAPI PHP库
此库允许您使用现代PHP7和面向对象的架构在项目中集成GatewayAPI.com API。关于其API、错误代码等完整描述,请参阅:https://gatewayapi.com/docs。
先决条件
您需要https://www.gatewayapi.com上的一个活跃账户才能使用此库。一旦您有了它,您需要在下拉菜单API -> API密钥下生成API密钥/密钥对。
安装
要将此库包含到您的项目中,请使用Composer进行安装。
此库需要PHP >= 7.1,并支持8.0、8.1和8.2。
composer require nickdnk/gatewayapi-php
使用方法
示例 #1:发送短信
use nickdnk\GatewayAPI\GatewayAPIHandler; use nickdnk\GatewayAPI\Entities\Request\Recipient; use nickdnk\GatewayAPI\Entities\Request\SMSMessage; // Pass `true` as the third parameter to use GatewayAPI in EU-only mode. // This requires an EU account. See https://gatewayapi.com/blog/new-eu-setup-for-gatewayapi-customers/. $handler = new GatewayAPIHandler('my_key', 'my_secret', false); $message1 = new SMSMessage( // The message you want to send. Include any placeholder tag strings. 'Hello, %FIRSTNAME%! Your code is: %CODE%.', // The name of the sender as seen by the recipient. // 1-11 ASCII characters, spaces are removed. 'MyService', // An array containing the recipient(s) you want to send the message // to. You can also pass an empty array and add recipients later on. // See the example below the constructor. [new Recipient(4512345678, ['John', '23523'])], // Arbitrary label added to your message(s). // Pass null if you don't need this. 'customer1', // The strings to replace in your message with tag values for each // recipient. Pass an empty array if you don't use tags in your message. ['%FIRSTNAME%', '%CODE%'], // The UNIX timestamp for when you want your message to be sent. // Pass null to send immediately. This should *not* be less than // the current UNIX time. This example sends in 1 hour. time() + 3600, // The message class to use. Note that prices vary. The secret class // requires approval by GatewayAPI on your account before you can use // it, otherwise you will get an error. SMSMessage::CLASS_STANDARD ); // If you prefer a shorter constructor, you can use the default values // and set your parameters after construction. $message2 = new SMSMessage('Hello %NAME%! Your code is: %CODE%', 'MyService'); $message2->setSendTime(time() + 3600); $message2->setClass(SMSMessage::CLASS_PREMIUM); $message2->setUserReference('customer1'); $message2->setTags(['%NAME%', '%CODE%']); $message2->setCallbackUrl('https://example.com/callback'); $message2->addRecipient(new Recipient(4587652222, ['Martha', '42442'])); try { // Note that a single SMSMessage must not contain more than 10,000 // recipients. If you want to send to more than 10,000 you should split // your recipients into several SMSMessages. You can, however, send // multiple SMSMessages in a single request. $result = $handler->deliverMessages( [ $message1, $message2 ] ); // All message IDs returned. $result->getMessageIds(); // The total cost of this request (all message IDs combined). $result->getTotalCost(); // Currency you were charged in. $result->getCurrency(); // The number of messages sent. For a message that's 3 SMSes long // with 1000 recipients, this will be 3000. $totalMessagesSent = $result->getTotalSMSCount(); // Messages sent to UK only. $ukMessages = isset($result->getCountries()['UK']) ? $result->getCountries()['UK'] : 0; } catch (\nickdnk\GatewayAPI\Exceptions\InsufficientFundsException $e) { /** * Extends GatewayRequestException. * * Your account has insufficient funds and you cannot send the * message(s) before you buy more credits at gatewayapi.com. * * The request body can be retried after you top up your balance. */ } catch (\nickdnk\GatewayAPI\Exceptions\MessageException $e) { /** * Extends GatewayRequestException. * * This should not happen if you properly use the library and pass * correct data into the functions, but it indicates that whatever * you're doing is not allowed by GatewayAPI. * * It can happen if you add the same phone number (recipient) twice * to an SMSMessage or if you don't use the tags function correctly, * such as not providing a tag value for a recipient within a message * that has a defined set of tags, or if you provide a tag value as * an integer. * * To add the same phone number twice to one request it must be in * different SMSMessage objects. * * Requests that throw this exception should *not* be retried! */ // The error code (may be null) $e->getGatewayAPIErrorCode(); // Error message, if present. $e->getMessage(); // Full response. $e->getResponse()->getBody(); } catch (\nickdnk\GatewayAPI\Exceptions\SuccessfulResponseParsingException $e) { /** * Extends GatewayRequestException. * * If you implement automatic retries of failed requests, you should * check for this exception. It is unlikely to ever occur, but it * could happen if GatewayAPI changed their API or there was an error * in the library. This could potentially trigger retries for requests * that succeeded which would be expensive as well as problematic * for recipients. */ // Error message. $e->getMessage(); // Full response. $e->getResponse()->getBody(); } catch (\nickdnk\GatewayAPI\Exceptions\UnauthorizedException $e) { /** * Extends GatewayRequestException. * * Something is wrong with your credentials or your IP is * banned. Make sure you API key and secret are valid or contact * customer support. * * The request body can be retried if you provide different * credentials (or fix whatever is wrong). */ // The error code (may be null) $e->getGatewayAPIErrorCode(); // Error message, if present. $e->getMessage(); // Full response. $e->getResponse()->getBody(); } catch (\nickdnk\GatewayAPI\Exceptions\GatewayServerException $e) { /** * Extends GatewayRequestException. * * Something is wrong with GatewayAPI.com. This exception simply * extends GatewayRequestException but only applies to 500-range * errors. * * The request body can (most likely) be retried. */ // The error code (may be null) $e->getGatewayAPIErrorCode(); // Error message. $e->getMessage(); // Full response. $e->getResponse()->getBody(); } catch (\nickdnk\GatewayAPI\Exceptions\ConnectionException $e) { /** * Connection to GatewayAPI failed or timed out. Try again or * check their server status at https://status.gatewayapi.com/ * * The request can/should be retried. This library does not * automatically retry requests that fail for this reason. */ // Error message. $e->getMessage(); } catch (\nickdnk\GatewayAPI\Exceptions\BaseException $e) { /** * Something else is wrong. * All exceptions inherit from this one, so you can catch this error * to handle all errors the same way or implement your own error * handler based on the error code. Remember to check for nulls. * * This exception is abstract, so you can check which class it is * and go from there. */ // Error message. $e->getMessage(); if ($e instanceof \nickdnk\GatewayAPI\Exceptions\GatewayServerException) { // The error code (may be null). $e->getGatewayAPIErrorCode(); $response = $e->getResponse(); $response->getBody(); $response->getStatusCode(); } }
示例 #2:取消计划中的消息
您可以根据发送时返回的ID取消基于计划的短信。由于此方法为每个消息ID创建一个请求池(每个消息ID一个请求),因此它不会抛出异常,而是返回一个CancelResult
数组。这些结果包含每个请求的状态和(如果失败)异常。
use nickdnk\GatewayAPI\Entities\CancelResult; use nickdnk\GatewayAPI\GatewayAPIHandler; $handler = new GatewayAPIHandler('my_key', 'my_secret'); $results = $handler->cancelScheduledMessages([1757284, 1757288]); foreach ($results as $cancelResult) { // The ID of the canceled message is always available. $cancelResult->getMessageId(); if ($cancelResult->getStatus() === CancelResult::STATUS_SUCCEEDED) { // Success. Obviously. } elseif ($cancelResult->getStatus() === CancelResult::STATUS_FAILED) { // Get the exception of a failed request. $cancelResult->getException(); } }
示例 #3:解析webhooks
您可以使用Webhook
类轻松解析从GatewayAPI发送到您的服务器的webhooks。它使用JWT头部来确保webhook未被篡改,并确实来自可信来源。
要设置webhooks,请转到API -> Web Hooks -> REST。在创建webhook后,在身份验证下指定JWT密钥。
可以发送两种类型的webhooks;投递状态通知和入站消息(MO流量)。两者都由Webhook
解析,并以相应的类返回。要读取入站消息,您必须订阅关键字或数字,在Subscriptions -> Keywords / Numbers下并将关键字或数字分配给webhook。
use nickdnk\GatewayAPI\Entities\Webhooks\DeliveryStatusWebhook; use nickdnk\GatewayAPI\Entities\Webhooks\IncomingMessageWebhook; use nickdnk\GatewayAPI\Entities\Webhooks\Webhook; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** * The webhook parser is based on PSR-7 allowing you to pass a $request * object directly into the class and get a webhook back. */ function (RequestInterface $request, ResponseInterface $response) { try { $webhook = Webhook::constructFromRequest($request, 'my_jwt_secret'); // Determine the type of webhook if you don't already know. if ($webhook instanceof DeliveryStatusWebhook) { $webhook->getPhoneNumber(); $webhook->getStatus(); } elseif ($webhook instanceof IncomingMessageWebhook) { $webhook->getPhoneNumber(); $webhook->getWebhookLabel(); $webhook->getMessageText(); } } catch (\nickdnk\GatewayAPI\Exceptions\WebhookException $exception) { // Something is wrong with the webhook or it was not correctly // signed. Take a look at your configuration. $exception->getMessage(); } } /** * Or if you don't have a PSR-7 request handy, you can pass the JWT * directly into this method instead. Note that the JWT contains * the entire payload, which is duplicated unsigned in the body of the * request. We don't read the request body at all. */ // JWT as a string, read from where-ever: $jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; try { $webhook = Webhook::constructFromJWT($jwt, 'my_jwt_secret'); } catch (\nickdnk\GatewayAPI\Exceptions\WebhookException $exception) { $exception->getMessage(); }
示例 #4:将SMSMessages或Recipients作为JSON处理
SMSMessage
和Recipient
被编码到发送到API的实际JSON中。如果您将这些输出放入队列或类似的东西,并希望在以后作为PHP对象检索它们,则可以使用这些方法进行操作。
use nickdnk\GatewayAPI\Entities\Request\Recipient; use nickdnk\GatewayAPI\Entities\Request\SMSMessage; $recipient = new Recipient(4587652222, ['Martha', '42442']); $json = json_encode($recipient); $recipient = Recipient::constructFromJSON($json); $message = new SMSMessage('Hello %NAME%! Your code is: %CODE%', 'MyService'); $message->setSendTime(time() + 3600); $message->setUserReference('reference'); $message->setTags(['%NAME%', '%CODE%']); $message->addRecipient($recipient); $json = json_encode($message); $smsMessage = SMSMessage::constructFromJSON($json); $smsMessage->getMessage(); $smsMessage->getRecipients();
测试
如果您想运行不需要凭证的单元测试,只需从项目的根目录运行vendor/bin/phpunit
即可。
如果您想测试与API交互的部分,必须在GatewayAPIHandlerTest.php
中提供凭证,并运行上述命令。请注意,这将发送实时短信,每次执行将消耗1个短信的信用。
联系
您可以通过nickdnk@hotmail.com联系我。
自行承担使用此库的风险。欢迎PR:)