amocrm/amocrm-api-library

amoCRM API 客户端

1.10.2 2024-09-05 18:14 UTC

README

amoCRM API Library

amoCRM API 库

Latest Version Build Status Total Downloads

本包提供了amoCRM API客户端,支持主要实体和OAuth 2.0协议授权。要使用此库,需要PHP版本不低于7.1。

目录

安装

可以使用composer安装此库

composer require amocrm/amocrm-api-library

入门和授权

要开始使用,您需要创建库对象

$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);

还提供了一个工厂类\AmoCRM\Client\AmoCRMApiClientFactory用于创建对象。要使用它,您需要实现接口\AmoCRM\OAuth\OAuthConfigInterface\AmoCRM\OAuth\OAuthServiceInterface

$apiClientFactory = new \AmoCRM\Client\AmoCRMApiClientFactory($oAuthConfig, $oAuthService);
$apiClient = $apiClientFactory->make();

使用工厂时,无需安装onAccessTokenRefresh回调,更新令牌时将自动调用$oAuthService的saveOAuthToken方法(\AmoCRM\OAuth\OAuthServiceInterface)。

然后需要从您的令牌存储中创建一个Access令牌对象(\League\OAuth2\Client\Token\AccessToken),并将其设置在API客户端中。

还需要将amoCRM账户的域名设置为子域名.amocrm.(ru/com)。

如果您想进一步处理新令牌(例如将其保存到令牌存储中),可以设置一个事件更新Access令牌的回调函数。

$apiClient->setAccessToken($accessToken)
        ->setAccountBaseDomain($accessToken->getValues()['baseDomain'])
        ->onAccessTokenRefresh(
            function (\League\OAuth2\Client\Token\AccessTokenInterface $accessToken, string $baseDomain) {
                saveToken(
                    [
                        'accessToken' => $accessToken->getToken(),
                        'refreshToken' => $accessToken->getRefreshToken(),
                        'expires' => $accessToken->getExpires(),
                        'baseDomain' => $baseDomain,
                    ]
                );
            });

可以通过两种方式将用户发送到授权页面

  1. 在网站上绘制按钮
$apiClient->getOAuthClient()->getOAuthButton(
            [
                'title' => 'Установить интеграцию',
                'compact' => true,
                'class_name' => 'className',
                'color' => 'default',
                'error_callback' => 'handleOauthError',
                'state' => $state,
            ]
        );
  1. 将用户发送到授权页面
$authorizationUrl = $apiClient->getOAuthClient()->getAuthorizeUrl([
            'state' => $state,
            'mode' => 'post_message', //post_message - редирект произойдет в открытом окне, popup - редирект произойдет в окне родителе
        ]);

header('Location: ' . $authorizationUrl);

您可以在地址为redirect_uri的处理程序中使用以下代码来获取Access Token

$accessToken = $apiClient->getOAuthClient()->getAccessTokenByCode($_GET['code']);

可以在examples/get_token.php文件中查看授权示例

使用账户特定用户的权限进行授权

从版本1.4.0开始,如果令牌是由账户管理员签发的,则可以授权为特定用户。

要使用账户用户进行授权,需要在\AmoCRM\Client\AmoCRMApiClient对象类型中设置用户ID。该方法将返回一个新的对象,其中已设置上下文。

$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);
$apiClientWithContext = $apiClient->withContextUserId(123);

安装自定义User Agent

从版本1.5.0开始,可以指定自己的User Agent来请求库。

$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);
$apiClient = $apiClient->setUserAgnet('App Name');

安装自定义回调处理器

从版本1.9.0开始,可以安装回调处理器来处理来自服务器的响应。

如果您需要处理额外的逻辑(例如记录服务器响应或重新定义204状态码的处理),可以设置一个事件处理响应的回调函数。

如果没有处理标准响应逻辑的需要,则回调应返回true

$apiClient = new \AmoCRM\Client\AmoCRMApiClient($clientId, $clientSecret, $redirectUri);

$this->apiClient
     ->setCheckHttpStatusCallback(
         function (ResponseInterface $response, $decodedBody) {
             if ($response->getStatusCode() === 204) {
                 return true;
             }

             $this->logger->info('Response: ', $decodedBody);
         }
     );

使用长期有效令牌进行授权

不久前,在amoCRM中出现了创建长期令牌的功能。它们可以很容易地与这个库一起使用。

要开始使用,您需要创建库对象

$apiClient = new \AmoCRM\Client\AmoCRMApiClient();

然后需要创建一个AmoCRM\Client\LongLivedAccessToken对象,该对象将用于API请求。

$longLivedAccessToken = new LongLivedAccessToken($accessToken);

然后需要将令牌和账户地址设置在库对象中

$apiClient->setAccessToken($longLivedAccessToken)
    ->setAccountBaseDomain('example.amocrm.ru');

完成这些简单步骤后,您就可以在令牌过期或被撤销之前向amoCRM发送请求。如果令牌被撤销或过期,则执行请求时将出现http状态码401错误。

使用库的方法

在库中使用了服务式方法。每个实体都有一个服务。每个方法都有自己的集合对象和模型。数据操作通过库中的集合和方法进行。

模型和集合具有toArray()toApi()方法,这些方法返回对象表示形式的数组以及发送到API的数据。

此外,还有一些用于处理集合的方法

  1. add(BaseApiModel $model): self - 将模型添加到集合末尾。
  2. prepend(BaseApiModel $value): self - 将模型添加到集合开头。
  3. all(): array - 返回集合中模型的数组。
  4. first(): ?BaseApiModel - 获取集合中的第一个模型。
  5. last(): ?BaseApiModel - 获取集合中的最后一个模型。
  6. count(): int - 获取集合中元素的数量。
  7. isEmpty(): bool - 检查集合是否为空。
  8. getBy($key, $value): ?BaseApiModel - 根据键值获取模型。
  9. replaceBy($key, $value, BaseApiModel $replacement): void - 根据键值替换模型。
  10. removeBy($key, $value): int - 根据键值删除模型,返回删除的模型数量。
  11. removeFirstBy($key, $value): bool - 根据键值删除第一个模型,如果模型被删除则返回true。
  12. chunk(int $size): array - 将集合分割成由指定长度的集合组成的数组。
  13. pluck(string $column): array - 根据属性名称获取模型集合的值数组。

在使用库时,请记住amoCRM API的限制。为了最佳数据操作,最好在具有批量处理的方法中一次创建/更新不超过50个实体。

需要记住错误处理,以及不要忘记存储令牌的安全性。 令牌泄露可能导致账户访问丢失。

支持的方法和服务

库支持大量API方法。方法被分组在服务对象中。可以通过调用库中的必要方法来获取服务对象,例如

$leadsService = $apiClient->leads();

目前有以下服务可用

大多数服务都有基本方法集

  1. getOne - 获取1个实体

    1. id (int|string) - 实体id
    2. with (array) - with参数数组,模型服务支持
    3. 执行结果将是实体模型
    getOne($id, array $with => []);
  2. get 获取多个实体

    1. filter (BaseEntityFilter) - 实体过滤器
    2. with (array) - with参数数组,模型服务支持
    3. 执行结果将是实体集合
    get(BaseEntityFilter $filter = null, array $with = []);
  3. addOne 创建1个实体

    1. model (BaseApiModel) - 创建实体的模型
    2. 执行结果将是实体模型
    addOne(BaseApiModel $model);
  4. add 批量创建实体

    1. collection (BaseApiCollection) - 创建实体的模型集合
    2. 执行结果将是实体模型集合
    add(BaseApiCollection $collection);
  5. updateOne 更新1个实体

    1. model (BaseApiModel) - 创建实体的模型
    2. 执行结果将是实体模型
    updateOne(BaseApiModel $model);
  6. update 批量更新实体

    1. collection (BaseApiCollection) - 创建实体的模型集合
    2. 执行结果将是实体模型集合
    update(BaseApiCollection $collection);
  7. syncOne 与服务器同步1个模型

    1. model (BaseApiModel) - 创建实体的模型集合
    2. with (array) - with参数数组,模型服务支持
    3. 执行结果将是实体模型集合
    syncOne(BaseApiModel $model, $with = []);

并非所有方法在所有服务中都可用。调用它们将抛出异常。

一些服务有特定方法,以下将讨论具有特定方法的服务。

leads服务中可用的方法

  1. addComplex 通过复合方法批量创建与相关联系人和公司关联的交易,支持重复控制
    1. collection (LeadsCollection) - 创建实体的模型集合
    2. 执行结果将是创建的新实体集合
    addComplex(LeadsCollection $collection);
  2. addOneComplex 通过复合方法创建与相关联系人和公司关联的交易,支持重复控制
    1. collection (LeadsCollection) - 创建实体的模型集合
    2. 执行结果将是创建的新交易模型
    addOneComplex(LeadModel $model);

有关综合创建方法的使用详情,请参阅示例

服务 getOAuthClient 中可用的方法

  1. getAuthorizeUrl 获取授权链接

    1. options (array)
      1. state (string) 应用程序状态
    2. 执行结果将是一条包含授权链接的字符串
    getAuthorizeUrl(array $options = []);
  2. getAccessTokenByCode 根据授权码获取 access token

    1. code (string) 授权码
    2. 执行结果将是一个 (AccessTokenInterface) 对象
    getAccessTokenByCode(string $code);
  3. getAccessTokenByRefreshToken 根据 refresh token 获取 access token

    1. accessToken (AccessTokenInterface) access token 对象
    2. 执行结果将是一个 (AccessTokenInterface) 对象
    getAccessTokenByRefreshToken(AccessTokenInterface $accessToken);
  4. setBaseDomain 设置基础域名,用于发送处理 token 所需的请求

    1. domain (string)
    setBaseDomain(string $domain);
  5. setAccessTokenRefreshCallback 设置当 access token 更新时将调用的 callback

    1. function (callable)
    setAccessTokenRefreshCallback(callable $function);
  6. getOAuthButton 设置当 access token 更新时将调用的 callback

    1. options (array)
      1. state (string) 应用程序状态
      2. color (string)
      3. title (string)
      4. compact (bool)
      5. class_name (string)
      6. error_callback (string)
      7. mode (string)
    2. 执行结果将是一条包含授权按钮 HTML 代码的字符串
    getOAuthButton(array $options = []);
  7. exchangeApiKey 方法用于将 API 密钥交换为授权码

    1. login - 交换 API 密钥的用户邮箱
    2. apiKey - 用户 API 密钥
    3. 授权码将被发送到应用程序设置中指定的 redirect_uri
    exchangeApiKey(string $login, string $apiKey);

以下服务中可用的连接方法 leadscontactscompaniescustomers

  1. link 绑定实体

    1. model (BaseApiModel) - 主实体模型
    2. links (LinksCollection|LinkModel) - 链接集合或模型
    3. 执行结果将是链接集合 (LinksCollection)
    link(BaseApiModel $model, $linkedEntities);
  2. getLinks 获取实体的链接

    1. model (BaseApiModel) - 主实体模型
    2. filter (LinksFilter) - 链接过滤器
    3. 执行结果将是链接集合 (LinksCollection)
    getLinks(BaseApiModel $model, LinksFilter $filter);
  3. unlink 解绑实体

    1. model (BaseApiModel) - 主实体模型
    2. links (LinksCollection|LinkModel) - 链接集合或模型
    3. 执行结果是一个 bool 值
    unlink(BaseApiModel $model, $linkedEntities);

以下服务中可用的删除方法 transactionslossReasonsstatusespipelinescustomFieldscustomFieldsGroupsrolescustomersStatusesentityFilesfiles

  1. delete

    1. model (BaseApiModel) - 实体模型
    2. 执行结果是一个 bool 值
    deleteOne(BaseApiModel $model);
  2. deleteOne

    1. collection (BaseApiCollection) - 实体模型集合
    2. 执行结果是一个 bool 值
    deleteOne(BaseApiModel $model);

customers 服务中可用的方法

  1. setMode 更改购买者模式(周期性购买或细分)。如果购买者功能关闭,则将打开。
    1. mode (string) - 模式类型(periodicity 或 segments)
    2. isEnabled (bool) - 购买者功能是否开启,默认为 true
    3. 执行结果将是启用模式的名称或 null(如果功能关闭)
    setMode(string $mode, bool $isEnabled = true);

customersBonusPoints 服务中可用的方法

  1. earnPoints 为购买者添加奖励积分

    1. model (BonusPointsActionModel) - 包含购买者 ID 和要添加的积分数量的模型
    2. 执行结果将是购买者更新后的积分数量或 null(如果发生错误)
    earnPoints(BonusPointsActionModel $bonusPointsActionModel)
  2. redeemPoints 扣除购买者的奖励积分

    1. model (BonusPointsActionModel) - 包含购买者 ID 和要扣除的积分数量的模型
    2. 执行结果将是购买者更新后的积分数量或 null(如果发生错误)
    redeemPoints(BonusPointsActionModel $bonusPointsActionModel)

notesentitySubscriptions 服务中可用的方法

  1. getByParentId 通过父实体 ID 获取数据
    1. parentId - 父实体 ID
    2. filter (BaseEntityFilter) - 过滤器
    3. with (array) - with参数数组,模型服务支持
    getByParentId(int $parentId, BaseEntityFilter $filter = null, array $with = []);

account 服务中可用的方法

  1. getCurrent
    1. with (array) - with参数数组,模型服务支持
    2. 执行结果将是 AccountModel 模型
    getCurrent(array $with = []);

unsorted 服务中可用的方法

  1. addOne 创建1个实体

    1. model (BaseApiModel) - 创建实体的模型
    2. 执行结果将是实体模型
    addOne(BaseApiModel $model);
  2. add 批量创建实体

    1. collection (BaseApiCollection) - 创建实体的模型集合
    2. 执行结果将是实体模型集合
    add(BaseApiCollection $collection);
  3. link

    1. model (BaseApiModel) - 未分类模型
    2. body (array) - 用于绑定的附加信息数组
    3. 执行结果将是 LinkUnsortedModel 模型
    link(BaseApiModel $unsortedModel, $body = []);
  4. accept

    1. model (BaseApiModel) - 未分类模型
    2. body (array) - 用于接受的附加信息数组
    3. 执行结果将是 AcceptUnsortedModel 模型
    accept(BaseApiModel $unsortedModel, $body = []);
  5. decline

    1. model (BaseApiModel) - 未分类模型
    2. body (array) - 用于拒绝的附加信息数组
    3. 执行结果将是 DeclineUnsortedModel 模型
    decline(BaseApiModel $unsortedModel, $body = []);
  6. summary

    1. filter (BaseEntityFilter) - 实体过滤器
    2. 执行结果将是 UnsortedSummaryModel 模型
    summary(BaseEntityFilter $filter);

webhooks 服务中可用的方法

  1. subscribe

    1. 模型(WebhookModel)- Webhook模型
    2. 执行结果为WebhookModel模型
    subscribe(WebhookModel $webhookModel);
  2. 取消订阅

    1. 模型(WebhookModel)- Webhook模型
    2. 执行结果是一个 bool 值
    unsubscribe(WebhookModel $webhookModel);

在widgets服务中可用的方法

  1. 安装

    1. 模型(WidgetModel)- 视图模型
    2. 执行结果为WidgetModel模型
    install(WidgetModel $widgetModel);
  2. 卸载

    1. 模型(WidgetModel)- 视图模型
    2. 执行结果为WidgetModel模型
    uninstall(WidgetModel $widgetModel);

在products服务中可用的方法

  1. 设置

    1. 执行结果为ProductsSettingsModel模型
    settings();
  2. 更新设置

    1. 模型(ProductsSettingsModel)- 视图模型
    2. 执行结果为ProductsSettingsModel模型
    updateSettings(ProductsSettingsModel $productsSettings);

在talks服务中可用的方法

  1. 关闭
    1. 模型(TalkCloseActionModel)- 关闭对话模型
    2. 执行结果为关闭对话或启动NPS机器人以关闭对话
    close(TalkCloseActionModel $closeAction)

在files服务中可用的方法

  1. uploadOne
    1. 模型(FileUploadModel)- 文件上传模型
    2. 执行结果为FileModel模型
    uploadOne(FileUploadModel $model);

在websiteButtons服务中可用的方法

  1. getOne - 获取1个实体
    1. id (int|string) - 源id
    2. with (array) - with参数数组,模型服务支持
    3. 执行结果将是WebsiteButtonModel实体模型
    getOne($id, array $with => []);
  2. get - 获取多个实体
    1. filter (BaseEntityFilter) - 实体过滤器
    2. with (array) - with参数数组,模型服务支持
    3. 执行结果将是WebsiteButtonsCollection集合,包含WebsiteButtonModel实体
    get(BaseEntityFilter $filter = null, array $with = []);
  3. createAsync - 添加类型为"网站按钮"的源
    1. 模型(WebsiteButtonCreateRequestModel)- 属性模型
      1. pipelineId (int) - 流程id
      2. trustedWebsites (array) - 将放置"网站按钮"的信任地址列表。例如 amocrm.ru, https://amocrm.ru
      3. isUsedInApp (true|false) - 如果按钮嵌入到应用程序中而不是网站,则为true
    2. 执行结果将是WebsiteButtonCreateResponseModel模型
    createAsync(WebsiteButtonCreateRequestModel $model);
  4. updateAsync - 添加额外的信任地址
    1. 模型(WebsiteButtonUpdateRequestModel)- 属性模型
      1. sourceId (int) - 源id
      2. trustedWebsitesToAdd (array) - 将放置"网站按钮"的信任地址列表
    2. 执行结果将是WebsiteButtonModel模型
    updateAsync(WebsiteButtonUpdateRequestModel $model);
  5. addOnlineChatAsync - 将"在线聊天"渠道添加到网站按钮
    1. sourceId - 源id
    2. 执行结果将是void值
    addOnlineChatAsync(int $sourceId);

错误处理

调用库中的方法可能会抛出AmoCRMApiException类型的错误。目前可用的错误类型如下,它们都继承自AmoCRMApiException

抛出的Exception有以下方法

  1. getErrorCode()
  2. getTitle()
  3. getLastRequestInfo()
  4. getDescription()

AmoCRMApiErrorResponseException类型的错误有getValidationErrors()方法,它将返回输入数据验证错误。

过滤器

目前库支持以下服务的过滤器

实体额外字段的处理

以下服务的实体可用额外字段

  1. 线索
  2. 联系人
  3. 公司
  4. 客户
  5. 目录元素

返回这些服务的模型,可以通过getCustomFieldsValues()方法获取字段。调用此方法返回CustomFieldsValuesCollection对象或null,如果没有字段值。

在CustomFieldsValuesCollection集合中,包含字段值模型,所有模型都继承自BaseCustomFieldValuesModel,但取决于字段类型。

继承自BaseCustomFieldValuesModel的模型有以下方法

  1. getFieldId, setFieldId - 获取/设置字段id
  2. getFieldType - 获取字段类型
  3. getFieldCode, setFieldCode - 获取/设置字段代码
  4. getFieldName, setFieldName - 获取/设置字段名称
  5. getValues, setValues - 获取/设置值集合

由于某些字段可能有多个值,因此值属性存储的是类型为BaseCustomFieldValueCollection的值集合。集合模型是BaseCustomFieldValueModel。

对象关系图

CustomFieldsValuesCollection 1 <---> n BaseCustomFieldValuesModel

BaseCustomFieldValuesModel::getValues() 1 <---> 1 BaseCustomFieldValueCollection

BaseCustomFieldValueCollection 1 <---> n BaseCustomFieldValueModel

对于不同类型的字段,我们已经准备了不同的模型和集合

值模型的命名空间 - \AmoCRM\Models\CustomFieldsValues\ValueModels

模型值集合所在的命名空间 - \AmoCRM\Models\CustomFieldsValues\ValueCollections

附加字段模型所在的命名空间 - \AmoCRM\Models\CustomFieldsValues

创建实体字段值集合的代码示例

//Создадим модель сущности
$lead = new LeadModel();
$lead->setId(1);
//Создадим коллекцию полей сущности
$leadCustomFieldsValues = new CustomFieldsValuesCollection();
//Создадим модель значений поля типа текст
$textCustomFieldValuesModel = new TextCustomFieldValuesModel();
//Укажем ID поля
$textCustomFieldValuesModel->setFieldId(123);
//Добавим значения
$textCustomFieldValuesModel->setValues(
    (new TextCustomFieldValueCollection())
        ->add((new TextCustomFieldValueModel())->setValue('Текст'))
);
//Добавим значение в коллекцию полей сущности
$leadCustomFieldsValues->add($textCustomFieldValuesModel);
//Установим в сущности эти поля
$lead->setCustomFieldsValues($leadCustomFieldsValues);

要删除字段值,可以使用特殊对象 \AmoCRM\Models\CustomFieldsValues\ValueCollections\NullCustomFieldValueCollection

传递此对象时,将字段值置为空。

示例

//Создадим модель сущности
$lead = new LeadModel();
$lead->setId(1);
//Создадим коллекцию полей сущности
$leadCustomFieldsValues = new CustomFieldsValuesCollection();
//Создадим модель значений поля типа текст
$textCustomFieldValuesModel = new TextCustomFieldValuesModel();
//Укажем ID поля
$textCustomFieldValuesModel->setFieldId(123);
//Обнулим значения
$textCustomFieldValuesModel->setValues(
    (new NullCustomFieldValueCollection())
);
//Добавим значение в коллекцию полей сущности
$leadCustomFieldsValues->add($textCustomFieldValuesModel);
//Установим сущности эти поля
$lead->setCustomFieldsValues($leadCustomFieldsValues);

处理实体标签

标签作为单独的服务 tags 可用。创建该服务时,您指定要与之合作的实体类型。

目前可用的

  1. EntityTypesInterface::LEADS,
  2. EntityTypesInterface::CONTACTS,
  3. EntityTypesInterface::COMPANIES,
  4. EntityTypesInterface::CUSTOMERS,

要处理特定实体的标签,需要与特定实体模型交互。通过 getTagssetTags 方法,您可以获取实体标签集合或设置它。

要更改标签,必须传递整个标签集合,否则标签可能会丢失。

示例:为实体添加/更改标签

//Создадим модель сущности
$lead = new LeadModel();
$lead->setId(1);
//Создадим коллекцию тегов с тегами и установим их в сущности
$lead->setTags((new TagsCollection())
    ->add(
        (new TagModel())
            ->setName('тег')
    )->add(
        (new TagModel())
            ->setId(123123)
    )
);

//Создадим модель сущности
$lead = new LeadModel();
$lead->setId(1);
//Создадим коллекцию тегов с тегами и установим их в сущности
$lead->setTags(
    TagsCollection::fromArray([
        [
            'name' => 'тег',
        ],
        [
            'id' => 123,
        ],
    ])
);

要删除标签,可以在 setTags 中传递特殊对象 \AmoCRM\Collections\NullTagsCollection

示例:从实体删除标签

//Создадим модель сущности
$lead = new LeadModel();
$lead->setId(1);
//Удалим теги
$lead->setTags((new NullTagsCollection()));

与来源工作时的特点

目前,只有通过集成创建的非解析聊天才考虑源。

添加源时,必需字段是 external_idname。集成可以在账户中创建不超过50个活跃源。删除源,例如具有 external_id: 'sales' 值的源,并在具有相同 external_id 的重复创建时,crm 可能会返回先前删除的源的 id。因此,不要在集成方面从 id 字段生成主键。

要使源在 WhatsApp CRM 插件的按钮中显示,必须指定包含以下内容的源字段 services

 [
   {
      "type": "whatsapp",
      "pages": [
         {
            "id": "<идентификатор или номер телефона>",
            "name": "My WhatsApp",
            "link": "<номер телефона>"
         }
      ]
   }
]

要正确地构建 services 字段,可以使用模型 \AmoCRM\Collections\Sources\SourceServicesCollection

默认源

默认源(具有 default=true 字段)只能有一个,或者根本不存在。如果没有默认源,则交易将指定为 API 集成源,其名称为集成名称(如通过 API 创建的非解析项)。

要更改默认源,只需将所需源的 default 字段设置为 true,则以前的源的 default 字段将设置为 false。但是,在删除默认源时,集成本身必须指定新的默认源。

集成迁移到多个源(适用于聊天集成)

默认源可以在集成迁移到多个源时使用,特别是如果集成支持“首先写入”选项。

例如初始状态
有一个账户连接了聊天集成,该集成仅支持1个源。目前我们不知道集成是如何安装的:通过 DP 或市场。

集成开始实施对多个源的支持,逻辑上将其分解为几个阶段

1阶段
集成能够处理 API 源(但不发送和接收 amojo 中的源)。添加默认源,它逻辑上对应于在没有多个源支持时使用的源。现在 crm 将为所有未明确指定源的聊天发送 external_id 的消息。

2阶段
集成能够在发送客户消息时处理源,并在创建聊天时指定 external_id。所有带有新消息的聊天现在都按源标记。

此外,集成现在处理源,并在发送管理员消息时考虑源,包括与客户开始聊天时的“首先写入”选项。

3阶段
集成允许账户管理员通过集成添加第二个和后续的源。所有通信都归某个源所有。

重要事项 默认源不会绑定到聊天,除非显式地与消息一起传递,否则在更改默认源时,未标记的聊天将“归”于新的源。

常量

主要的常量位于接口 \AmoCRM\Helpers\EntityTypesInterface 中。

以下类/接口也提供了常量

  1. \AmoCRM\OAuth\AmoCRMOAuth::BUTTON_COLORS - 网站按钮上的可用颜色
  2. \AmoCRM\Models\Unsorted\BaseUnsortedModel - 未分类代码的常量
  3. \AmoCRM\Models\CustomFields\BirthdayCustomFieldModel - 生日字段中 remind 属性的常量
  4. \AmoCRM\Models\Interfaces\CallInterface - 电话状态常量
  5. \AmoCRM\EntitiesServices\Interfaces\HasParentEntity - 拥有父实体的方法的请求键常量(目前只有 notes)
  6. \AmoCRM\Models\CustomFieldsValues\ValueModels\ItemsCustomFieldValueModel - Items 字段值键常量
  7. \AmoCRM\Models\Rights\RightModel - 与权限相关的常量
  8. \AmoCRM\Models\AccountModel - 服务 account 的 with 参数常量
  9. \AmoCRM\Models\TaskModel - 默认任务类型的常量
  10. \AmoCRM\Models\NoteType\TargetingNote - 用于定位注释的支持外部服务常量(添加 DP)
  11. \AmoCRM\Models\RoleModel - 服务 roles 的 with 参数常量
  12. \AmoCRM\Models\Factories\NoteFactory - 注释类型常量
  13. \AmoCRM\Models\NoteType\MessageCashierNote - "消息给收银员" 注释的状态
  14. \AmoCRM\Models\LeadModel - 服务 leads 的 with 参数常量
  15. \AmoCRM\Filters\Interfaces\HasOrderInterface - 排序常量
  16. \AmoCRM\Models\EventModel - 服务 events 的 with 参数常量
  17. \AmoCRM\Models\CustomFields\CustomFieldModel - 字段类型常量
  18. \AmoCRM\Models\Customers\CustomerModel - 服务 customers 的 with 参数常量
  19. \AmoCRM\Models\ContactModel - 服务 contacts 的 with 参数常量
  20. \AmoCRM\Models\CompanyModel - 服务 companies 的 with 参数常量
  21. \AmoCRM\Models\CatalogElementModel - 服务 catalogElements 的 with 参数常量
  22. \AmoCRM\Enum\InvoicesCustomFieldsEnums - 处理目录账单字段的常量(从版本 0.12 开始,状态常量已移动到 \AmoCRM\Enum\Invoices\BillStatusEnumCode)
  23. \AmoCRM\Enum\Chats\Templates\Buttons\ButtonsEnums - 聊天模板按钮类型
  24. \AmoCRM\Enum\Sources\SourceServiceTypeEnum - 来源服务的类型
  25. \AmoCRM\Enum\Tags\TagColorsEnum - 标签的可能颜色
  26. \AmoCRM\Enum\Invoices\BillStatusEnumCode - 账单/购买的预置状态
  27. \AmoCRM\Enum\SuppliersCustomFieldsEnums - 供应商字段属性常量

处理子域名账户变更

/**
 * Получим модель с информацией о домене аккаунта по access_token
 * Подробнее: @see AccountDomainModel
 *
 * Запрос уходит на www.amocrm.ru/oauth2/account/subdomain
 * С Authorization: Bearer {access_token}
 * curl 'https://www.amocrm.ru/oauth2/account/subdomain' -H 'Authorization: Bearer {access_token}'
 *
 * @example examples/get_account_subdomain.php
 */
$accountDomain = $apiClient->getOAuthClient()
        ->getAccountDomain($accessToken);

// Возьмём из полученной модели текущий subdomain аккаунта и засетим наш апи клиент
$apiClient->setAccountBaseDomain($accountDomain->getSubdomain());
// ... дальше продолжаем работу с апи клиентом

一次性集成令牌的解密

// Как пример, получим заголовки с реквеста
// И получим нужный нам X-Auth-Token
$token = $_SERVER['HTTP_X_AUTH_TOKEN'];

try {
    /**
     * Одноразовый токен для интеграций, для того чтобы его получить используйте
     * метод this.$authorizedAjax() в своей интеграции
     * Подробнее: @link https://www.amocrm.ru/developers/content/web_sdk/mechanics
     *
     * Данный токен должен передаваться в заголовках вместе с запросом на ваш удаленный сервер
     * X-Auth-Token: {disposable_token}
     * Время жизни токена: 30 минут
     *
     * Расшифруем пришедший токен и получим модель с информацией
     * Подробнее: @see DisposableTokenModel
     */
    $disposableTokenModel = $apiClient->getOAuthClient()
        ->parseDisposableToken($token);

    var_dump($disposableTokenModel->toArray());
} catch (DisposableTokenExpiredException $e) {
    // Время жизни токена истекло
    printError($e);
    die;
} catch (DisposableTokenInvalidDestinationException $e) {
    // Не прошёл проверку на адресата токена
    printError($e);
    die;
} catch (DisposableTokenVerificationFailedException $e) {
    // Токен не прошел проверку подписи
    printError($e);
    die;
}

您还可以解析 Salesbot/Marketingbot 的单次令牌模型。为此,需要调用 parseBotDisposableToken 方法

$token = 'XXX';
try {
    /**
     * Одноразовый токен для ботов, его вы можете получить, сделав вызов widget_request в виджете в боте
     * Подробнее: @link https://www.amocrm.ru/developers/content/digital_pipeline/salesbot#handler-widget_request
     *
     * Данный токен содержит в себе информацию об аккаунте и о сущности, с которой работает бот
     * Для продолжения бота необходимо сделать запрос на метод, который был получен в теле хука
     * Подробнее: @link https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widget-continue  
     *
     * Расшифруем пришедший токен и получим модель с информацией
     * Подробнее: @see BotDisposableTokenModel
     */
    $botDisposableTokenModel = $apiClient->getOAuthClient()
        ->parseBotDisposableToken($token);

    var_dump($botDisposableTokenModel->toArray());
} catch (DisposableTokenExpiredException $e) {
    // Время жизни токена истекло
    printError($e);
    die;
} catch (DisposableTokenInvalidDestinationException $e) {
    // Не прошёл проверку на адресата токена
    printError($e);
    die;
} catch (DisposableTokenVerificationFailedException $e) {
    // Токен не прошел проверку подписи
    printError($e);
    die;
}

处理货币

/** @var AmoCRMApiClient $apiClient */

# Получим сервис для работы с валютами
$service = $apiClient->currencies();

# Получение списка валют
try {
    $collection = $service->get();
    var_dump($collection);
} catch (AmoCRMApiException $e) {
    printError($e);
    die;
}

# Получение списка валют с фильтром
$filter = new CurrenciesFilter();
$filter->setLimit(50);
$filter->setPage(2);

try {
    $collection = $service->get($filter);
    var_dump($collection);
} catch (AmoCRMApiException $e) {
    printError($e);
    die;
}

示例

在当前存储库中有一个名为 examples 的文件夹,其中包含各种示例。

为了运行它们,需要向其中添加一个 .env 文件,内容如下,并指定您的值

CLIENT_ID="UUID интеграци"
CLIENT_SECRET="Секретный ключ интеграции"
CLIENT_REDIRECT_URI="https://example.com/examples/get_token.php (Важно обратить внимание, что он должен содержать в себе точно тот адрес, который был указан при создании интеграции)"

然后,可以通过命令 composer serve 启动本地服务器。配置完成后,请在浏览器中转到 http://localhost:8181/examples/get_token.php 以获取访问令牌。要访问外部本地服务器,可以使用 ngrok.io 服务。

登录后,可以通过浏览器访问示例来检查其工作情况。请注意,为了正确运行示例,需要检查示例中的实体 ID。

处理问题

如果您在使用库时遇到问题,可以创建一个 Issue,它将在有机会时被处理。

在创建时,请详细描述问题,附加代码示例,以及来自 getLastRequestInfo 的响应。

请记住从示例中删除不应公开的任何重要数据。

还可以考虑对库进行改进的建议。

您可以通过创建带有描述的Issue以及包含Issue引用的Pull request来提出对库原始代码的修改/更改。它们将被审查,并被接受或拒绝。有些Pull Request可能会没有回复和行动,如果这些修改潜在可行,但当前不是项目的关键。

如果您遇到了amoCRM的功能问题,请通过您账户中的聊天联系技术支持。

许可证

MIT