Отправка писем в LPTracker по API с почтового ящика

Все чаще и чаще предприниматели для увеличения конверсии своего бизнеса используют готовые сторонние сервисы, одним из таких является LPTracker CRM ( CRM — система управления взаимоотношениями с клиентами ).
Права как и у всех систем она имеет свои недостатки, одной из которых невозможность напрямую выгружать с почтовых ящиков через протоколы POP3/IMAP, но к счастью у них хорошо реализована API, с которой очень просто взаимодействовать. Правда и не без своих нюансов, о которым будет сказано позднее.
Принцип взаимодействия
Есть сайт сгенерированный на конструкторе Tilda, На нем отображается email для связи и пару форм, при заполнении и отправке которых отсылается письма на тот же контактный почтовый адрес. Все пришедшие письма хранятся на хостинге ( в почтовом клиенте ).
Будет реализована проверка новых писем на почтовом сервере, после чего будет происходить отправка писем в систему LPTracker.
Сбор писем в одном месте
Для упрощения работы с выгрузкой новых писем на основном контактном email необходимо установить отправку копий пришедших писем на новый ящик — lpt.temp@exemple.com.
Так же необходимо создать сам почтовый ящик через панель предоставляемой хостингом, в моем случае это ISP.
Теперь все пришедшие письма будут дополнительно копироваться на новый почтовый ящик.
Хранение данных в базе данных (БД)
Теперь необходимо создать базу данных, где будет храниться все письма и связанные идентификаторы с ними из LPTracker.
Для этого, если используете ISP менеджер, переходим «Инструменты»->»phpMyAdmin», и заходим в web-рожицу БД.
Создаем новую базу данные в которой создаем две таблицы:
- tr_mails — хранит в себе сами письма
- tr_users — хранит в себе контактные данные
CREATE TABLE IF NOT EXISTS `tr_mails` (
`mail_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`mail_subject` varchar(250) DEFAULT NULL,
`mail_lead` int(10) unsigned DEFAULT NULL,
`mail_reply` int(11) DEFAULT NULL,
`mail_html` text,
`mail_files` text,
`mail_obj` text,
`mail_api` int(11) unsigned NOT NULL DEFAULT '0',
`timeadd` datetime DEFAULT NULL,
PRIMARY KEY (`mail_id`),
KEY `user_id` (`user_id`),
KEY `mail_subject` (`mail_subject`),
KEY `timeadd` (`timeadd`),
KEY `mail_reply` (`mail_reply`),
KEY `mail_api` (`mail_api`),
KEY `mail_lead` (`mail_lead`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `tr_users` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(250) DEFAULT NULL,
`user_email` varchar(250) NOT NULL,
`timeadd` datetime DEFAULT NULL,
`timeupdate` datetime DEFAULT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `user_email` (`user_email`),
KEY `user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
ALTER TABLE `tr_mails`
ADD CONSTRAINT `tr_mails_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `tr_users` (`user_id`),
ADD CONSTRAINT `tr_mails_ibfk_2` FOREIGN KEY (`mail_reply`) REFERENCES `tr_mails` (`mail_id`);
Так же, последней командой создаем связь между таблицами.
Подготовительные работы закончены, теперь осталось только писать логику.
Выгрузка писем
Для того что бы распределить нагрузку и функциональность будет создано два контроллера, которые будут отвечать за свой этап взаимодействия:
- imap.php — контроллер получения новых писем с почтового клиента, удаления и запись их в БД
- api.php — проверка новых писем в БД, проверка/запись клиентов в системе LPTracker, после чего отправка писем, после чего обновление БД присваивая уникальный идентификатор CRM
Для корректной работы файл конфигураций будет вынесен в отдельный файл config.php с содержимым:
//доменное имя сервера
$domenName = 'exemple.com';
//конфиг LPTracker
$lpConf = [
'login' => '...', //имя пользователя от аккаунта CRM
'password' => '...', //пароль от аккаунта CRM
'service' => 'MailImapForTracker', //имя приложения
];
//конфиг почтового клиента
$mailConf = [
'login' => '...', // логин для авторизации
'password' => '...', //пароль для авторизации
'service' => '...', // сервер почты, к примеру "hosting.ru:993/imap/ssl"
];
//конфиг БД
$dbConf = [
'hostname' => 'localhost', //расположение сервера
'database' => '...', //имя базы данных
'username' => '...', //имя пользователя для подключения
'password' => '...', //пароль для подключения
'dbcollat' => 'utf8', //кодировка
];
Теперь два основных файла, imap.php
header("Content-Type: text/html; charset=utf-8");
require_once('config.php');
require_once('core/db.php');
require_once('core/PhpImap/__autoload.php');
//функция записи нового пользователя
function insert_user($data = array()){
return !empty($data) ? \DB::insert("
INSERT IGNORE INTO `tr_users`
(`user_name`, `user_email`, `timeadd`, `timeupdate`)
VALUES (?, ?, ?, ?)", $data
) : null;
}
//функция записи нового письма
function insert_mail($data = array()){
return !empty($data) ? \DB::insert("
INSERT IGNORE INTO `tr_mails`
(`user_id`, `mail_subject`, `mail_html`, `mail_obj`, `mail_files`, `timeadd`)
VALUES (?, ?, ?, ?, ?, ?)", $data
) : null;
}
//доавляем новое письмо как реплику
function insert_mail_reply($data = array()){
return !empty($data) ? \DB::insert("
INSERT IGNORE INTO `tr_mails`
(`user_id`, `mail_subject`, `mail_reply`, `mail_html`, `mail_obj`, `mail_files`, `timeadd`)
VALUES (?, ?, ?, ?, ?, ?, ?)", $data
) : null;
}
//создать дерево директорий
function mkdir_r($dirName, $rights=0777){
$dirs = explode('/', $dirName);
$dir='';
foreach ($dirs as $part) {
$dir .= $part.'/';
if (!is_dir(__DIR__.'/'.$dir) && strlen(__DIR__.'/'.$dir)>0)
mkdir(__DIR__.'/'.$dir, $rights);
}
return __DIR__.'/'.$dir;
}
//удалить пустую директорию
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
$clear = true;
foreach ($objects as $object) {
if (
$object != "." AND
$object != ".."
) {
$clear = false;
}
}
if($clear){
return @rmdir($dir);
}
}
return false;
}
//проверка вывода ошибок
try{
//формирование папки для хранения файлов
$dirTempArr = [ date("Ym"), date("d"), date("His") ];
//создание временной папки для хранения файлов
$dirTemp = mkdir_r( "files/" . implode('/', $dirTempArr) );
$mess = '';
// подключение к почтовому клиенту
$mailbox = new PhpImap\Mailbox('{'.$mailConf['service'].'}INBOX', $mailConf['login'], $mailConf['password'], $dirTemp);
// подсчек общее количество писем, получение индефикаторов
$mailsIds = $mailbox->searchMailbox();
if( !empty($mailsIds) ) {
//подключаемся к базе
\DB::getInstance($dbConf);
//получаем все письма
$mail = array();
foreach ($mailsIds as $id){
//получили письмо
$mail = $mailbox->getMail($id);
//основные параметры
$mess = array(
'name' => trim( $mail->fromName ),
'mail' => trim( $mail->fromAddress ),
'html' => strip_tags( trim( $mail->textPlain ) ? trim( $mail->textPlain ) : trim( $mail->textHtml ) ),
'date' => trim( $mail->date ),
'files' => serialize( $mail->getAttachments() ),
'obj' => serialize($mail),
'subject' => trim($mail->subject),
);
//провери историю
if( mb_substr($mess['subject'], 0, 3) == "Re:" )
{ // ответ
$dbResult = \DB::select("
SELECT u.*,
m.mail_id, m.mail_subject, m.mail_reply, m.mail_html, m.timeadd
FROM tr_users AS u
LEFT JOIN tr_mails AS m ON u.user_id=m.user_id AND m.mail_subject=?
WHERE u.user_email=? AND u.user_name=?", array(
trim(mb_substr($mess['subject'], 3)),
$mess['mail'],
$mess['name'],
));
if( !empty($dbResult) ){
if(isset($dbResult[0], $dbResult[0]->mail_id)){
insert_mail_reply(array(
$dbResult[0]->user_id,
$mess['subject'],
$dbResult[0]->mail_id,
$mess['html'],
$mess['obj'],
$mess['files'],
$mess['date'],
));
}else{
//нет сообщения, добавляем новую реплику
insert_mail(array(
$dbResult[0]->user_id,
$mess['subject'],
$mess['html'],
$mess['obj'],
$mess['files'],
$mess['date'],
));
}
}else{
//пользователя не существует, добавляем пользователя
$usrUid = insert_user(array(
$mess['name'],
$mess['mail'],
$mess['date'],
$mess['date'],
));
if($usrUid){
//добавляем новую реплику
insert_mail(array(
$usrUid,
$mess['subject'],
$mess['html'],
$mess['obj'],
$mess['files'],
$mess['date'],
));
}
}
}
else
{ // новое сообщение
$dbResult = \DB::select("
SELECT *
FROM tr_users AS u
WHERE u.user_email=? AND u.user_name=?", array(
$mess['mail'],
$mess['name'],
));
if( !empty($dbResult) ){
//нет сообщения, добавляем новую реплику
insert_mail(array(
$dbResult[0]->user_id,
$mess['subject'],
$mess['html'],
$mess['obj'],
$mess['files'],
$mess['date'],
));
}else{
//пользователя не существует, добавляем пользователя
$usrUid = insert_user(array(
$mess['name'],
$mess['mail'],
$mess['date'],
$mess['date'],
));
if($usrUid){
//добавляем новую реплику
insert_mail(array(
$usrUid,
$mess['subject'],
$mess['html'],
$mess['obj'],
$mess['files'],
$mess['date'],
));
}
}
}
$mailbox->deleteMail($id);
}
}else{
$mess = 'Писем нет :) ';
}
//удаляем папку если файлы не созданы
for ( $i=count($dirTempArr); $i; $i-- ){
if( !rrmdir($dirTemp) ){
break;
}
if( $i and isset($dirTempArr[$i-1]) ){
$dirTemp = str_replace('/'.$dirTempArr[$i-1], '', $dirTemp);
}
}
exit($mess);
}catch (\Exception $e){
print_r($e->getMessage());
}
и api.php
header("Content-Type: text/html; charset=utf-8");
require_once('config.php');
require_once('core/db.php');
require_once('core/PhpImap/__autoload.php');
require_once ('vendor/autoload.php');
use LPTracker\LPTracker;
//подключаемся к базе
\DB::getInstance($dbConf);
$dbMails = \DB::select("
SELECT u.*,
m.mail_id, m.mail_subject, m.mail_reply, m.mail_html, m.mail_api, m.mail_files, m.timeadd, m.mail_obj
FROM tr_mails AS m
LEFT JOIN tr_users AS u ON u.user_id=m.user_id
WHERE m.mail_api = ?
LIMIT 5", array(
0,
));
//проверка новых писем
if(empty($dbMails)){
exit("Писем нет");
}
//авторизируемся в системе
$api = new LPTracker($lpConf);
try{
//проверка токена
if( empty($api) or !$api->getToken() ) {
$api->logout();
exit("Токен не получен");
}
//Получить список проектов
$projects = $api->getProjectList();
if( empty($projects) ) {
$api->logout();
exit("Нет проектов");
}
//проход по проектам
foreach ($projects as $project){
if( $project->getId() == 51595 ){
//проход по письмам
foreach ($dbMails as $mail){
//проверка заполненности данных
if(!$mail->mail_html){
$mail->mail_obj = unserialize($mail->mail_obj);
$mail->mail_html = strip_tags(isset($mail->mail_obj->textHtml) ? $mail->mail_obj->textHtml : '');
$mail->mail_obj = null;
}
//ищем контакт
$contact = $api->searchContacts(
$project->getId(),
array(
'email' => $mail->user_email
)
);
//пользователя нет
if(empty($contact)){
//создаем пользователя
$contact = $api->createContact(
$project,
array(
array(
"type" => "email",
"data" => $mail->user_email
)
),
array(
"name" => $mail->user_name
)
);
}else{
$contact = $contact[0];
}
$lead = 1;
$comment = 1;
//получени контакт
if( !empty($contact) ){
//получаем лиды контакта
$lead = $api->contactLeads(
$contact
);
//проверка существование лида
if( empty($lead) ){
//создаем лид
$lead = $api->createLead(
$contact,
array(
'name' => $mail->mail_subject,
'source' => 'email',
)
);
}else{
$leadRes = null;
foreach ( $lead as $l ){
if( $l instanceof \LPTracker\models\Lead ){
foreach ( $l->getCustoms() as $n ){
if( $n instanceof \LPTracker\models\Custom and $n->getType() == 'funnel' ){
$leadRes = $l;
}
}
}
}
$lead = ($leadRes) ?
$leadRes :
$api->createLead(
$contact,
array(
'name' => $mail->mail_subject,
'source' => 'email',
)
);
}
//проверка нужности добавления файла
$listFiles = [];
$files = [];
if( $mail->mail_files ){
$mail->mail_files = unserialize($mail->mail_files);
if(!empty($mail->mail_files)){
foreach ($mail->mail_files as $file){
if($file and isset($file->filePath) and $file->filePath and is_string($file->filePath)){
preg_match ( '/[\S]+'.$domenName.'\/([\S]*)$/i' , $file->filePath , $matches);
if( isset($matches[1]) and $matches[1]){
$listFiles[] = 'http://'.$domenName.'/'.$matches[1];
}
//добавляем файл к лиду
$res = $api->addFileToLead(
$lead,
$file->filePath
);
if( $res ){
$files[] = $res;
}
}
}
}
}
$listFiles = isset($listFiles[0]) ? ' ||=> Файлы: '.implode(' | ', $listFiles) : '';
//добавляем комментарий к лиду
$comment = $api->addCommentToLead(
$lead,
$mail->mail_html . $listFiles
);
}
//обновляем входящее сообщение
\DB::update("
UPDATE tr_mails
SET mail_api = ?, mail_lead = ?
WHERE mail_id = ?",
array(
($comment===1)? $comment : $comment->getId(),
($lead===1)? $lead : $lead->getId(),
(isset($mail->mail_id) and $mail->mail_id)?
$mail->mail_id : 1,
));//*/
}
}
}
}catch (\Exception $e){
print_r($e->getMessage());
}
@$api->logout();
Теперь дополнительные файлы.
Создаем папку «core» и в ней файл для работы с БД «db.php»:
<?php
interface DBInterface{
//старт файла
public function __construct();
//запрещаем клонирование объекта
public function __clone();
//запрещаем восстановление
public function __wakeup();
//инициализация обьекта
public static function getInstance( array $config = array() );
//запрос с возвратом ответа
public static function select(string $query, array $val = null): array;
//добавление материала
public static function insert(string $query, array $val = null): int;
//обновление материала
public static function update(string $query, array $val = null): int;
//удаление материала
public static function delete(string $query, array $val = null): int;
//удаление материала
public static function error(): string;
//Закрытие соединения
public function __destruct();
}
class DB implements DBInterface{
//сам бьект
protected static $_instance = [
'pdo' => null,
'error' => null,
'config' => null,
];
//старт файла
public function __construct(){}
//запрещаем клонирование объекта
public function __clone() {}
//запрещаем восстановление
public function __wakeup() {}
public static function getInstance( array $config = array() ) {
$error = (!isset(
$config['hostname'],
$config['database'],
$config['username'],
$config['password'],
$config['dbcollat'])
) ? "Error connection to database." : false;
//инициалезируем обьект
if (self::$_instance === null) self::$_instance = new self;
self::$_instance['error'] = $error;
self::$_instance['config'] = $config;
//проверка ошибок
if( !self::$_instance['error'] ){
//подключение к БД
try{
//драйвер подключения
$dbconn = "mysql:host=$config[hostname];dbname=$config[database]";
//процесс подключения
self::$_instance['pdo'] = new PDO( $dbconn, $config['username'], $config['password'] );
//установка параметров
self::$_instance['pdo']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//переводим кодировку
self::$_instance['pdo']->exec("SET NAMES '$config[dbcollat]'");
}catch(PDOException $e){ //вывод ошибки подключения
self::$_instance['error'] = $e->getMessage();
}
}
//возвращаем подключение
return self::$_instance;
}
//запрос с возвратом ответа
private static function query(string $query, array $val): PDOStatement {
$stmt = null;
try{
//проверка наличия ошибок
if(self::$_instance['error']){
return null;
}
//проверка передаваемых параметров
if(!$val){
$stmt = self::$_instance['pdo']->query($query);
$stmt->execute();
}else{
$stmt = self::$_instance['pdo']->prepare($query);
$stmt->execute($val);
}
}catch(PDOException $e){ }
//возврат результата
return $stmt;
}
//запрос с возвратом ответа
public static function select(string $query = '', array $val = null): array{
//отправка результата
$query = self::query($query, $val);
//проверка ответа
if( $query === null ){
return array();
}
//возврат результата
return (isset($query->errorInfo()[0]) and $query->errorInfo()[0] == 00000) ?
$query->fetchAll(PDO::FETCH_OBJ) : array();
}
//добавление материала
public static function insert(string $query = '', array $val = null): int {
//отправка результата
$query = self::query($query, $val);
//проверка ответа
if( $query === null ){
return 0;
}
//возврат результата
return self::$_instance['pdo']->lastInsertId();
}
//обновление материала
public static function update(string $query = '', array $val = null): int {
//отправка результата
$query = self::query($query, $val);
//проверка ответа
if( $query === null ){
return 0;
}
//возврат результата
return (isset($query->errorInfo()[0]) and $query->errorInfo()[0] == 00000)?
$query->rowCount() : 0;
}
//удаление материала
public static function delete(string $query = '', array $val = null): int {
//отправка результата
$query = self::query($query, $val);
//проверка ответа
if( $query === null ){
return 0;
}
//возврат результата
return (isset($query->errorInfo()[0]) and $query->errorInfo()[0] == 00000)?
$query->rowCount() : 0;
}
//удаление материала
public static function error(): string {
return self::$_instance['error'] ?? '';
}
//Закрытие соединения
public function __destruct(){
self::$_instance['pdo'] = null;
}
}
Следующим модулем нам необходимо подключить библиотеку «php-imap» с github скачав архив по ссылке или через консоль (терминал) клонировать через команду git так, что бы папка «PhpImap» лежала в корне директории «core» для возможности собирать письма с почтового клиента по протоколу IMAP:
cd core/ && git clone git@github.com:tarsy-club/php-imap.git
и последним штрихом надо добавить официальную SDK от LPTracker для работы с API через композер в корень проекта:
composer require lptracker/php-sdk
Добавляем планировщик на оба контроллера с периодичностью каждые 2 минуты запуска «2/ * * * *»
Проект готов, теперь он будет при получании новых писем на email отсылать его копию на временную почту , откуда по крону будут получены новые письма и записаны в базу, вторым кроном будут выбраны из базы новые письма и по их данным будет произведен поиск через SDK в LPTracker совпадающих контактов, в случае если контакты не будут найдены они будут созданы. И для каждого контакта если не будет активной заявки, будет создана новая и в комментариях написано само тело сообщения.
Нюанс работы API
Но без ложки дектя не обойдется.
На момент написания статьи в официальном SDK LPTracker нет загрузка файлов и вызываемой функции «addFileToLead» не существует, поэтому на этом месте в случае передачи файлов будет выводиться ошибка, поэтому либо необходимо из файла «api.php» все что связанно с загрузкой файлов, либо отредактировать официальную библиотеку ( можно и создать собственный модуль для взаимодействия с API, но это будет плохим тоном и займет больше времени в разработке и дальнейшей поддержке).
Для работы с файлами первым делом надо создать модель для самих файлов.
Переходим в директорию «vendor/lptracker/php-sdk/src/LPTracker/» (дальнейшая разработка будет проходить относительно данной папки) и в папке «models» создаем файл «File.php» с содержимым:
<?php
namespace LPTracker\models;
use LPTracker\exceptions\LPTrackerSDKException;
/**
* Class Lead
* @package LPTracker\models
*/
class File extends Model
{
/**
* @var integer
*/
protected $id;
/**
* @var integer
*/
protected $leadId;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $mime;
/**
* @var string
*/
protected $data;
/**
* @var string
*/
protected $file;
/**
* @var \DateTime
*/
protected $createdAt;
/**
* @var array
*/
protected $options = [];
/**
* Lead constructor.
*
* @param array $fileData
*/
public function __construct(array $fileData = [])
{
if ( ! empty($fileData['id'])) {
$this->id = intval($fileData['id']);
}
if ( ! empty($fileData['lead_id'])) {
$this->leadId = intval($fileData['lead_id']);
}
if ( ! empty($fileData['name'])) {
$this->name = $fileData['name'];
}
if ( ! empty($fileData['mime'])) {
$this->mime = $fileData['mime'];
}
if ( ! empty($fileData['data'])) {
$this->data = $fileData['data'];
}
if ( ! empty($fileData['file'])) {
$this->setFile($fileData['file']);
}
if ( ! empty($fileData['file_date'])) {
$date = \DateTime::createFromFormat('d.m.Y H:i', $fileData['file_date']);
$this->setCreatedAt($date);
}
if ( ! empty($fileData['params']) && is_array($fileData['params'])) {
$this->options['params'] = $fileData['params'];
}
}
/**
* @param bool $toSave
*
* @return array
*/
public function toArray($toSave = false)
{
$result = [];
if ( ! empty($this->id)) {
$result['id'] = $this->getId();
}
if ( ! empty($this->name)) {
$result['name'] = $this->getName();
}
if ( ! empty($this->mime)) {
$result['mime'] = $this->getMime();
}
if ( ! empty($this->data)) {
$result['data'] = $this->getData();
}
if ( ! empty($this->createdAt)) {
$result['file_date'] = $this->getCreatedAt()->format('d.m.Y H:i');
}
foreach ($this->options as $key => $value) {
$result[$key] = $value;
}
return $result;
}
/**
* @return bool
* @throws LPTrackerSDKException
*/
public function validate()
{
if (empty($this->leadId)) {
throw new LPTrackerSDKException('Lead ID is required');
}
if ( intval($this->leadId) <= 0) {
throw new LPTrackerSDKException('Invalid lead id');
}
return ( empty($this->name) or empty($this->mime) or empty($this->data) ) ? false : true;
}
/**
* @return int
*/
public function getId()
{
return intval($this->id);
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getMime()
{
return $this->mime;
}
/**
* @param string $mime
*
* @return $this
*/
public function setMime($mime)
{
$this->mime = $mime;
return $this;
}
/**
* @return string
*/
public function getData()
{
return $this->data;
}
/**
* @param string $data
*
* @return $this
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* @param string $url
*
* @return $this
*/
public function setFile($url)
{
$type = null;
if( empty($this->data) and file_exists($url) and filesize($url) < 1077777 ){
$type = mime_content_type($url);
$this->data = 'data:' . $type . ';base64,' . base64_encode(file_get_contents($url));
}
//параметры
if( !empty($this->data) ){
$path_parts = pathinfo($url);
$this->name = !empty($this->name) ?
$this->name :
( $path_parts['filename'] ? $path_parts['filename'] : 'not name' );
$this->mime = $this->mime ?
$this->mime : $type;
}else{
$this->name = null;
$this->mime = null;
}
return $this;
}
/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param \DateTime $createdAt
*
* @return $this
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
}
Теперь SDK знает о новой модели для файлов и знает как с ними работать, осталось только создать запуск метода «addFileToLead».
Заходим в файл «LPTracker.php» и добавляем внутр класса «LPTracker» новый метод:
/**
* @param $lead
* @param $url
*
* @return File
* @throws LPTrackerSDKException
* @throws exceptions\LPTrackerResponseException
* @throws exceptions\LPTrackerServerException
*/
public function addFileToLead($lead, $url)
{
$lead = ($lead instanceof Lead) ? $lead->getId() : intval($lead);
$file = new File([
'lead_id' => $lead,
'file' => $url
]);
$res = null;
if( $file->validate() ) {
//создаем файл
$response = LPTrackerRequest::sendRequest(
"/lead/$lead/file",
$file->toArray(true),
'POST',
$this->token,
$this->address
);
$res = new File($response);//*/
}
return $res;
}
и в самом начале добавляем инициализацию модели
use LPTracker\models\File;
Все, код готов к тестированию.