铁路媒体/ helpscout-api-php
Help Scout API v2 客户端 - musora media 分支
Requires
- php: ^7.3|^8.0
- guzzlehttp/guzzle: ^6.3|^7.0.1
- rize/uri-template: 0.3.5
- webmozart/assert: ^1.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.3
- mockery/mockery: ^1.1
- phpstan/phpstan: ^0.10.1
- phpunit/phpunit: ^8.4
- ramsey/uuid: ^4.1
Suggests
- helpscout/api-laravel: API adapters for use with Laravel and Lumen
- dev-main
- 3.8.0
- 3.7.0
- 3.6.1
- 3.6.0
- 3.5.2
- 3.5.1
- 3.5.0
- 3.4.0
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.1
- 3.0.0
- v2.x-dev
- 2.7.0
- 2.6.0
- 2.5.0
- 2.4.1
- 2.4.0
- 2.3.10
- 2.3.9
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 2.0.0-beta
- v1.x-dev
- 1.9.6
- 1.9.5
- 1.9.4
- 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.0
- 1.3.11
- dev-report-endpoints
- dev-develop
This package is auto-updated.
Last update: 2024-09-15 17:04:00 UTC
README
这是官方的 Help Scout PHP 客户端。此客户端包含用于轻松与 Help Scout 邮箱 API 交互的方法。
目录
安装
建议使用 Composer 安装客户端。
composer require helpscout/api "^3.0"
对于 Laravel 项目,请查看 helpscout/api-laravel
使用
您应该在应用程序中使用 Composer 的自动加载器来自动加载类。以下所有示例都假设您已在代码中包含此内容
require_once 'vendor/autoload.php';
身份验证
使用工厂创建一个客户端。创建后,您可以设置各种凭证以进行请求。
use HelpScout\Api\ApiClientFactory; $client = ApiClientFactory::createClient(); // Set Client credentials if using that grant type. Using this approach will lazily fetch an access token on-demand // when needed. $client->useClientCredentials($appId, $appSecret); // Set Access token directly if you have it $client->setAccessToken('abc123'); // Use a refresh token to get a new access token $client->useRefreshToken($appId, $appSecret, $refreshToken);
注意
所有凭证类型都会触发一个预检请求来获取访问令牌(HTTP 'POST' 请求)。为了避免这种情况,请在使用客户端的 setAccessToken
方法之前设置访问令牌。
$client = ApiClientFactory::createClient(); $client->setAccessToken('asdfasdf');
如果可用,将始终使用访问令牌,无论是否设置了其他凭证。
自动刷新过期的令牌
当请求由于身份验证错误而失败时,SDK 可以自动尝试获取新的刷新令牌,然后自动重试给定的请求。要启用此功能,您可以在创建 ApiClient 时提供一个回调,该回调可用于根据您的需求在其他进程中使用令牌持久化
$client = ApiClientFactory::createClient([], function (Authenticator $authenticator) { // This $authenticator contains the refreshed token echo 'New token: '.$authenticator->accessToken().PHP_EOL; });
回调也可以是任何实现 HelpScout\Api\Http\Auth\HandlesTokenRefreshes
的类实例
use HelpScout\Api\Http\Auth\HandlesTokenRefreshes; use HelpScout\Api\Http\Authenticator; $callback = new class implements HandlesTokenRefreshes { public function whenTokenRefreshed(Authenticator $authenticator) { // @todo Persist the token } }; $client = ApiClientFactory::createClient([], $callback);
授权码流程
由于 授权码 只适用于单次使用,您在执行其他 API 调用之前需要用访问令牌和刷新令牌交换代码。您还需要持久化令牌以供以后重用。
$client = ApiClientFactory::createClient(); $client = $client->swapAuthorizationCodeForReusableTokens( $appId, $appSecret, $authorizationCode ); $credentials = $client->getAuthenticator()->getTokens(); echo $credentials['access_token'].PHP_EOL; echo $credentials['refresh_token'].PHP_EOL; echo $credentials['expires_in'].PHP_EOL;
除了提供访问/刷新令牌外,这还将设置当前身份验证以使用这些令牌,因此您可以自由地进行后续请求而无需重新初始化客户端。
// uses the one-time authorization code for auth
$client = $client->swapAuthorizationCodeForReusableTokens(
$appId,
$appSecret,
$authorizationCode
);
// uses access/refresh tokens for auth
$client->users()->list();
示例
本 README 包含许多示例,但您还可以在 ./examples
中找到更多供您实验的示例。
客户
获取客户。获取客户时,其所有实体(电子邮件地址、电话号码、社交档案等)都会在相同的请求中预加载。
$customer = $client->customers()->get($customerId);
获取客户。
$customers = $client->customers()->list();
使用过滤器获取客户。
如 API 文档中所述,客户列表可以按各种字段进行筛选。CustomerFields 类提供了一个简单的接口来设置筛选值。例如
use HelpScout\Api\Customers\CustomerFilters; $filter = (new CustomerFilters()) ->byFirstName('Tom') ->byLastName('Graham'); $customers = $client->customers()->list($filter);
创建客户。
use HelpScout\Api\Customers\Customer; $customer = new Customer(); $customer->setFirstName('Bob'); // ... try { $customerId = $client->customers()->create($customer); } catch (\HelpScout\Api\Exception\ValidationErrorException $e) { var_dump($e->getError()->getErrors()); }
更新客户。
// ... $customer->setFirstName('Bob'); $client->customers()->update($customer);
电子邮件
创建客户电子邮件。
use HelpScout\Api\Customers\Entry\Email; $email = new Email(); $email->setValue('lucy@helpscout.com'); $email->setType('work'); // ... $client->customerEntry()->createEmail($customerId, $email);
更新客户电子邮件。
// ... $email->setType('home'); $client->customerEntry()->updateEmail($customerId, $email);
删除客户电子邮件。
$client->customerEntry()->deleteEmail($customerId, $emailId);
地址
创建客户地址。
use HelpScout\Api\Customers\Entry\Address; $address = new Address(); $address->setCity('Boston'); // ... $client->customerEntry()->createAddress($customerId, $address);
更新客户地址。
// ... $address->setCity('Boston'); $client->customerEntry()->updateAddress($customerId, $address);
删除客户地址。
$client->customerEntry()->deleteAddress($customerId);
电话号码
创建客户电话。
use HelpScout\Api\Customers\Entry\Phone; $phone = new Phone(); $phone->setValue('123456789'); $phone->setType('work'); // ... $client->customerEntry()->createPhone($customerId, $phone);
更新客户电话。
// ... $phone->setType('home'); $client->customerEntry()->updatePhone($customerId, $phone);
删除客户电话。
$client->customerEntry()->deletePhone($customerId, $phoneId);
聊天处理
创建客户聊天。
use HelpScout\Api\Customers\Entry\ChatHandle; $chat = new ChatHandle(); $chat->setValue('1239134812348'); $chat->setType('icq'); // ... $client->customerEntry()->createChat($customerId, $chat);
更新客户聊天。
// ... $chat->setValue('1230148584583'); $client->customerEntry()->updateChat($customerId, $chat);
删除客户聊天。
$client->customerEntry()->deleteChat($customerId, $chatId);
社交资料
创建客户社交资料。
use HelpScout\Api\Customers\Entry\SocialProfile; $socialProfile = new SocialProfile(); $socialProfile->setValue('helpscout'); $socialProfile->setType('twitter'); // ... $client->customerEntry()->createSocialProfile($customerId, $socialProfile);
更新客户社交资料。
// ... $socialProfile->setType('facebook'); $client->customerEntry()->updateSocialProfile($customerId, $socialProfile);
删除客户社交资料。
$client->customerEntry()->deleteSocialProfile($customerId, $socialProfileId);
网站
创建客户网站。
use HelpScout\Api\Customers\Entry\Website; $website = new Website(); $website->setValue('https://www.helpscout.com'); // ... $client->customerEntry()->createWebsite($customerId, $website);
更新客户网站。
// ... $website->setValue('https://www.helpscout.net'); $client->customerEntry()->updateWebsite($customerId, $website);
删除客户网站。
$client->customerEntry()->deleteWebsite($customerId, $websiteId);
属性
获取客户的属性及其值
use HelpScout\Api\Customers\Entry\Website; $customer = $client->customers()->get(418048101); // ... foreach ($customer->getProperties() as $property) { echo $property->getName().': '.$property->getValue().PHP_EOL; }
邮箱
获取邮箱。
$mailbox = $client->mailboxes()->get($mailboxId);
获取预加载子实体的邮箱。
邮箱实体有两个相关子实体
- 字段
- 文件夹
在获取邮箱时,可以预先加载这些子实体,以减少多次方法调用的需求。使用MailboxRequest
类来描述哪些子实体应该被预先加载。例如
use HelpScout\Api\Mailboxes\MailboxRequest; $request = (new MailboxRequest) ->withFields() ->withFolders(); $mailbox = $client->mailboxes()->get($mailboxId, $request); $fields = $mailbox->getFields(); $folders = $mailbox->getFolders();
获取邮箱。
$mailboxes = $client->mailboxes()->list();
获取预加载子实体的邮箱。
use HelpScout\Api\Mailboxes\MailboxRequest; $request = (new MailboxRequest) ->withFields() ->withFolders(); $mailboxes = $client->mailboxes()->list($request);
对话
获取会话。
$conversation = $client->conversations()->get($conversationId);
您可以轻松地懒加载会话的额外信息/关系。例如
use HelpScout\Api\Conversations\ConversationRequest; $request = (new ConversationRequest) ->withMailbox() ->withPrimaryCustomer() ->withCreatedByCustomer() ->withCreatedByUser() ->withClosedBy() ->withThreads() ->withAssignee(); $conversation = $client->conversations()->get($conversationId, $request); $mailbox = $conversation->getMailbox(); $primaryCustomer = $conversation->getCustomer();
获取会话。
$conversations = $client->conversations()->list();
获取预加载子实体的会话。
use HelpScout\Api\Conversations\ConversationRequest; $request = (new ConversationRequest) ->withMailbox() ->withPrimaryCustomer() ->withCreatedByCustomer() ->withCreatedByUser() ->withClosedBy() ->withThreads() ->withAssignee(); $conversations = $client->conversations()->list(null, $request);
基于一组过滤器缩小会话列表。
use HelpScout\Api\Conversations\ConversationFilters; $filters = (new ConversationFilters()) ->inMailbox(1) ->inFolder(13) ->inStatus('all') ->hasTag('testing') ->assignedTo(1771) ->modifiedSince(new DateTime('2017-05-06T09:04:23+05:00')) ->byNumber(42) ->sortField('createdAt') ->sortOrder('asc') ->withQuery('query') ->byCustomField(123, 'blue'); $conversations = $client->conversations()->list($filters);
您甚至可以将过滤器与预加载子实体结合在一个请求中
use HelpScout\Api\Conversations\ConversationRequest; use HelpScout\Api\Conversations\ConversationFilters; $request = (new ConversationRequest) ->withMailbox() ->withThreads(); $filters = (new ConversationFilters()) ->inMailbox(1) ->inFolder(13) ->byCustomField(123, 'blue'); $conversations = $client->conversations()->list($filters, $request);
更新会话上的自定义字段
$customField = new CustomField(); $customField->setId(10524); $customField->setValue(new DateTime('today')); $client->conversations()->updateCustomFields($conversationId, [$customField]);
创建一个新的会话,就像客户向您的邮箱发送电子邮件一样。
// We can specify either the id or email for the Customer $customer = new Customer(); $customer->addEmail('my-customer@company.com'); $thread = new CustomerThread(); $thread->setCustomer($customer); $thread->setText('Test'); $conversation = new Conversation(); $conversation->setSubject('Testing the PHP SDK v2: Phone Thread'); $conversation->setStatus('active'); $conversation->setType('email'); $conversation->setMailboxId(80261); $conversation->setCustomer($customer); $conversation->setThreads(new Collection([ $thread, ])); // You can optionally add tags $tag = new Tag(); $tag->setName('testing'); $conversation->addTag($tag); try { $conversationId = $client->conversations()->create($conversation); } catch (ValidationErrorException $e) { var_dump($e->getError()->getErrors()); }
以下是一些您可能创建会话的其他示例场景
电话会话,由Help Scout用户发起
$user = $client->users()->get(31231);
$customer = new Customer();
$customer->setId(193338443);
$thread = new PhoneThread();
$thread->setCustomer($customer);
$thread->setCreatedByUser($user);
$thread->setText('Test');
$conversation = new Conversation();
$conversation->setSubject('Testing the PHP SDK v2: Phone Thread');
$conversation->setStatus('active');
$conversation->setType('phone');
$conversation->setMailboxId(80261);
$conversation->setCustomer($noteCustomer);
$conversation->setCreatedByUser($user);
$conversation->setThreads(new Collection([
$thread,
]));
聊天会话,由客户发起
$noteCustomer = new Customer();
$noteCustomer->setId(163315601);
$thread = new ChatThread();
$thread->setCustomer($noteCustomer);
$thread->setText('Test');
$conversation = new Conversation();
$conversation->setSubject('Testing the PHP SDK v2: Chat Thread');
$conversation->setStatus('active');
$conversation->setType('chat');
$conversation->setAssignTo(271315);
$conversation->setMailboxId(138367);
$conversation->setCustomer($noteCustomer);
$conversation->setThreads(new Collection([
$thread,
]));
// Also adding a tag to this conversation
$tag = new Tag();
$tag->setName('testing');
$conversation->addTag($tag);
$conversationId = $client->conversations()->create($conversation);
删除会话
$client->conversations()->delete($conversationId);
更新现有会话
$client->conversations()->move($conversationId, 18); $client->conversations()->updateSubject($conversationId, 'Need more help please'); $client->conversations()->updateCustomer($conversationId, 6854); $client->conversations()->publishDraft($conversationId); $client->conversations()->updateStatus($conversationId, 'closed'); $client->conversations()->assign($conversationId, 127); $client->conversations()->unassign($conversationId);
线程
聊天线程
为会话创建新的聊天线程。
use HelpScout\Api\Customers\Customer; use HelpScout\Api\Conversations\Threads\ChatThread; $thread = new ChatThread(); $customer = new Customer(); $customer->setId(163487350); $thread->setCustomer($customer); $thread->setText('Thanks for reaching out to us!'); $client->threads()->create($conversationId, $thread);
客户线程
为会话创建新的客户线程。
use HelpScout\Api\Customers\Customer; use HelpScout\Api\Conversations\Threads\CustomerThread; $thread = new CustomerThread(); $customer = new Customer(); $customer->setId(163487350); $thread->setCustomer($customer); $thread->setText('Please help me figure this out'); $client->threads()->create($conversationId, $thread);
备注线程
为会话创建新的备注线程。
use HelpScout\Api\Conversations\Threads\NoteThread; $thread->setText('We are still looking into this'); $client->threads()->create($conversationId, $thread);
电话线程
为会话创建新的电话线程。
use HelpScout\Api\Customers\Customer; use HelpScout\Api\Conversations\Threads\PhoneThread; $thread = new PhoneThread(); $customer = new Customer(); $customer->setId(163487350); $thread->setCustomer($customer); $thread->setText('This customer called and spoke with us directly about the delay on their order'); $client->threads()->create($conversationId, $thread);
回复线程
为会话创建新的回复线程。
use HelpScout\Api\Customers\Customer; use HelpScout\Api\Conversations\Threads\ReplyThread; $thread = new ReplyThread(); $customer = new Customer(); $customer->setId(163487350); $thread->setCustomer($customer); $thread->setText("Thanks, we'll be with you shortly!"); $client->threads()->create($conversationId, $thread);
获取会话的线程。
$threads = $client->threads()->list($conversationId);
附件
获取附件。
$attachment = $client->attachments()->get($conversationId, $attachmentId); $attachment->getData(); // attached file's contents
创建附件
use HelpScout\Api\Conversations\Threads\Attachments\AttachmentFactory; use HelpScout\Api\Support\Filesystem; $attachmentFactory = new AttachmentFactory(new Filesystem()); $attachment = $attachmentFactory->make('path/to/profile.jpg'); $attachment->getMimeType(); // image/jpeg $attachment->getFilename(); // profile.jpg $attachment->getData(); // base64 encoded contents of the file $client->attachments()->create($conversationId, $threadId, $attachment);
删除附件
$client->attachments()->delete($conversationId, $attachmentId);
聊天
获取聊天
$chat = $client->chats()->get($chatId);
列出聊天事件
$events = $client->chats()->events($chatId);
标签
列出标签
$tags = $client->tags()->list();
团队
列出团队
$teams = $client->teams()->list();
列出团队成员
$users = $client->teams()->members($teamId);
用户
获取用户。
$user = $client->users()->get($userId);
获取用户。
$users = $client->users()->list();
基于一组过滤器缩小用户列表。
use HelpScout\Api\Users\UserFilters; $filters = (new UserFilters()) ->inMailbox(1) ->byEmail('tester@test.com'); $users = $client->users()->list($filters);
报告
在运行SDK报告时,请参考开发者文档以获取确切的端点、参数和响应格式。虽然此SDK中的大多数端点都只是调用API的透传方法,但也有一些便利之处。
首先,对于start
、end
、previousStart
和previousEnd
参数,您可以传递格式化的日期时间字符串或实现\DateTimeInterface
的任何对象作为参数。客户端将自动将这些对象转换为正确格式。
对于接受多个值(mailboxes
、tags
、types
和folders
)的参数,您可以传递值数组,让客户端转换为正确格式。如果您愿意,也可以传递单个值(或以逗号分隔的值列表)。
要运行报告,请使用ApiClient
实例上可用的runReport
方法。将您想使用的报告类的类路径作为第一个参数,并将报告参数数组作为第二个参数。请确保参数数组中的键与文档中指定的URL参数相匹配。客户端将把API返回的JSON响应转换为数组。
// Example of running the Company Overall Report // https://developer.helpscout.com/mailbox-api/endpoints/reports/company/reports-company-overall/ use HelpScout\Api\Reports\Company; $params = [ // Date interval fields can be passed as an object implementing the \DateTimeInterface // or as a string in the 'Y-m-d\Th:m:s\Z' format. All times should be in UTC. 'start' => new \DateTime('-7 days'), 'end' => new \DateTimeImmutable(), 'previousStart' => '2015-01-01T00:00:00Z', 'previousEnd' => '2015-01-31T23:59:59Z', // Fields accepting multiple values can be passed as an array or a comma-separated string 'mailboxes' => [123, 321], 'tags' => '987,789', 'types' => ['chat', 'email'], 'folders' => [111, 222] ]; $report = $client->runReport(Company\Overall::class, $params);
Webhooks
获取webhook。
$webhook = $client->webhooks()->get($webhookId);
列出webhook。
$webhooks = $client->webhooks()->list();
创建一个webhook。
新创建的webhook的默认状态是启用
。
use HelpScout\Api\Webhooks\Webhook; $data = [ 'url' => 'http://bad-url.com', 'events' => ['convo.assigned', 'convo.moved'], 'secret' => 'notARealSecret' ]; $webhook = new Webhook(); $webhook->hydrate($data); // ... $client->webhooks()->create($webhook);
更新webhook
此操作将替换整个webhook实体,因此您必须再次提供密钥。更新后,webhook将再次处于启用
状态。
$webhook->setUrl('http://bad-url.com/really_really_bad'); $webhook->setSecret('mZ9XbGHodY'); $client->webhooks()->update($webhook);
删除webhook。
$client->webhooks()->delete($webhookId);
处理传入的webhook
您还可以使用SDK轻松处理传入的webhook。签名验证将在创建新对象时发生,因此无需检查其是否有效。如果签名不匹配,则IncomingWebhook
对象的构造函数将抛出InvalidSignatureException
异常,以告知您存在问题。
// Build it from globals $incoming = IncomingWebhook::makeFromGlobals($secret);
// or build using a request object that satisfies the PSR-7 RequestInterface /** @var RequestInterface $request */ $request = new Request(...); $secret = 'superSekretKey'; $incoming = new IncomingWebhook($request, $secret);
一旦您拥有传入的webhook对象,您可以检查有效负载的类型(客户、会话或测试),以及检索数据(查看示例)。如果是客户或会话,您可以检索相关的模型。否则,您可以获取有效负载作为关联数组或标准类对象。
工作流程
获取所有工作流程的分页列表。
$workflows = $client->workflows()->list();
在会话列表上运行手动工作流程。
$convos = [ 123, 321 ]; $client->workflows()->runWorkflow($id, $convos);
将工作流程状态更改为“活动”或“非活动”
$client->workflows()->updateStatus($id, 'active');
错误处理
客户端直接抛出的任何异常都将实现HelpScout\Api\Exception
,而HTTP错误将导致抛出Http\Client\Exception\RequestException
。
如果未提供OAuth2令牌或令牌无效,则将抛出HelpScout\Api\Exception\AuthenticationException
。
验证
如果提交给API的请求中存在任何验证错误,您将遇到ValidationErrorException
。以下是如何使用该异常的快速示例
try { // do something } catch (\HelpScout\Api\Exception\ValidationErrorException $e) { $error = $e->getError(); var_dump( // A reference id for that request. Including this anytime you contact Help Scout will // empower us to dig right to the heart of the issue $error->getCorrelationId(), // Details about the invalid fields in the request $error->getErrors() ); exit; }
分页
在获取实体集合时,客户端将返回HelpScout\Api\Entity\Collection
的实例。如果端点支持分页,则返回HelpScout\Api\Entity\PagedCollection
的实例。
/** @var PagedCollection $users */ $users = $client->users()->list(); // Iterate over the first page of results foreach ($users as $user) { echo $users->getFirstName(); } // The current page number $users->getPageNumber(); // The total number of pages $users->getTotalPageCount(); // Load the next page $nextUsers = $users->getNextPage(); // Load the previous page $previousUsers = $users->getPreviousPage(); // Load the first page $firstUsers = $users->getFirstPage(); // Load the last page $lastUsers = $users->getLastPage(); // Load a specific page $otherUsers = $users->getPage(12); // Paged results are accessible as normal arrays, so you can simply iterate over them foreach ($otherUsers as $user) { echo $user->getFirstName(); }
测试
SDK在ApiClient
类中提供了一个方便的mock
方法。要使用它,请传递您想要模拟的端点名称。您将返回一个\Mockery\MockInterface
对象。一旦设置了模拟,对那个端点的后续调用将返回模拟对象。
// From within the tests/ApiClientTest.php file... public function testMockReturnsProperMock() { $client = ApiClientFactory::createClient(); $mockedWorkflows = $client->mock('workflows'); $this->assertInstanceOf(WorkflowsEndpoint::class, $mockedWorkflows); $this->assertInstanceOf(MockInterface::class, $mockedWorkflows); $this->assertSame( $mockedWorkflows, $client->workflows() ); }
一旦模拟了一个端点,您可能希望在以后清除它。为此,您可以在ApiClient
上使用clearMock($endpoint)
方法。
获取支持
请为任何SDK相关问题或功能请求提交一个问题。对于可能涉及敏感客户或账户数据的问题,请通过电子邮件与我们联系help@helpscout.com。