Мне поставили задачу: сформировать документ через Adobe API. Требований было минимум — главное сформировать документ из шаблона. Шаблон я мог отформатировать в нужный мне формат без проблем. Но сам формат, как его использовать и как это связать с API я не знал. Поэтому нырнул в документацию.
После пары часов изучения, я отчаялся. Информации было море, но нужной информации не нашел. Но зато нашел несколько вариантов документации, пару статей и несколько видео-уроков. Всё это не приблизило меня к цели ни на шаг.
Но спустя несколько дней, огромное количество нервов и желания сдаться, я всё-таки решил задачу. И буду рад поделиться решением тут.
Adobe Document Generation API
Первая задача: какой из Adobe сервисов нужен.
Adobe Document Generation API. Он отвечает за генерацию, сжатие, конвертирование и иную работу с документами. Но нас интересует только генерация.
Чтобы его использовать, необходимо выполнить следующие шаги:
-
Создать приложение
-
Получить токен доступа (access token)
-
Подготовить шаблон
-
Загрузить шаблон
-
Сформировать итоговый документ
Создаем приложение
Переходим по ссылке https://developer.adobe.com/console/projects, затем:
-
Нажимаем «Create new Project»
-
Нажимаем «Add to project» — выбираем API и ищем там PDF Services API
-
Выбираем автоматическую генерацию приватных ключей, жмем «Continue» кучу раз
-
Ждем пока Adobe сгенерирует доступы и предложит скачать их
Переходим в приложение во вкладку «Credentials» где будут данные для генерации JWT.
Если Adobe не прислал Client Secret, пересоздаем его тут же и сохраняем себе.
Получаем токен доступа (access token)
Первым делом мы создаем JWT строку, параметры которой указаны тут: https://developer.adobe.com/developer-console/docs/guides/authentication/JWT/
<?php use Firebase\JWT\JWT; $organizationID = 'Organization ID с вкладки Credentials'; $accountID = 'Technical Account ID с вкладки Credentials'; $clientID = 'Client ID с вкладки Credentials'; $privateKey = file_get_contents('путь до файла private.key из архива'); $payload = [ 'exp' => time() + 60 * 60 * 2, 'iss' => $organizationID, 'sub' => $accountID, 'aud' => 'https://ims-na1.adobelogin.com/c/' . $clientID, 'https://ims-na1.adobelogin.com/s/ent_documentcloud_sdk' => true ]; // Используется firebase/php-jwt $jwt = JWT::encode($payload, $privateKey, 'RS256');
Далее запрашиваем access token. Используем запрос, который я нашел в официальной коллекции Adobe в Postman(Adobe Target Admin APIs/Exchange JWT for Access token):
<?php // JWT получен выше $clientID = 'Client ID с вкладки Credentials'; $clientSecret = 'Client Secret с вкладки Credentials'; $query = [ 'client_id' => $clientID, 'client_secret' => $clientSecret, 'jwt_token' => $jwt, ]; // Используется фасад Http из Laravel. Но суть его в формировании обычного POST запроса. Да, без тела. Так надо $response = Http::post('https://ims-na1.adobelogin.com/ims/exchange/jwt?' . http_build_query($query)); $token = $response->json('access_token');
В ответе будет поле access_token с нашим токеном. Либо ошибка и её описание.
Подготавливаем шаблон
Шаблон заполняется JSON данными. А в самом документе необходимо указать ключи этого самого JSON.
Пример JSON:
{ "name": "Dmitry", "meta":{ "age": 23 } }
В шаблоне можно указать ключи {{name}}
и {{meta.age}}
Загружаем шаблон
Adobe не хранит у себя файлы. Он использует сервера Amazon.
Поэтому сперва получаем через Adobe доступ к Amazon, а затем загружаем наш шаблон.
Получаем доступ к Amazon:
<?php // access token был получен выше $token = ''; $clientID = 'Client ID с вкладки Credentials'; // У docx mime тип "application/vnd.openxmlformats-officedocument.wordprocessingml.document" $mime = 'mime тип шаблона. Обычно это docx' // Используется фасад Http Laravel: // - POST запрос // - Тело запроса raw application/json // - Авторизация Bearer с access token // - Доп. заголовок "x-api-key" с вашим ClientID $response = Http ::withToken($token) ->asJson() ->withHeaders([ 'x-api-key' => $clientID ]) ->post('https://pdf-services.adobe.io/assets', [ "mediaType" => $mime ]); $assetID = $response->json('assetID'); $uploadUri = $response->json('uploadUri'); // В ответе будет assetID и uploadUri. Второй нужен для загрузки файла
Загружаем шаблон:
<?php // $uploadUri был получен выше $mime = 'mime тип загружаемого шаблона' // Тут привычный всем Guzzle: // - PUT запрос // - Тело запроса файл в байтах // - Доп. заголовок "Content-Type" с вашим mime типом загружаемого файла $request = new \GuzzleHttp\Psr7\Request( 'PUT', $uploadUri, ['Content-Type' => $mime], file_get_contents('путь до шаблона') ); $client = new Client(); $response = $client->send($request); // Если не 200 код, то явно была ошибка if ($response->getStatusCode() != 200) { // Обработка ошибки, иначе использовать assetID полученный выше }
Шаблон загружен
Формируем документ из шаблона
Отправляем запрос на формирование документа:
<?php // assetID был получен выше $clientID = 'Client ID с вкладки Credentials'; // access token был получен выше $token = ''; $data = [ "name" => "Dmitry", "meta" => ["age" => 23] ]; // Используется фасад Http Laravel: // - POST запрос // - Тело запроса raw application/json // - Авторизация Bearer с access token // - Доп. заголовок "x-api-key" с вашим ClientID $response = Http ::withToken($token) ->asJson() ->withHeaders([ 'x-api-key' => $clientID ]) ->post('https://pdf-services.adobe.io/operation/documentgeneration', [ "assetID" => $assetID, "outputFormat" => "pdf", "jsonDataForMerge" => $data ]); // Если статус не 201, то произошла ошибка if ($response->status() != 201) { // Обработка ошибки } // Необходимо забрать заголовок x-request-id $requestID = $response->header('x-request-id')
После отправки запроса, необходимо проверить статус запроса:
<?php // x-request-id был получен выше $requestID = ''; // access token был получен выше $token = ''; $clientID = 'Client ID с вкладки Credentials'; // Используется фасад Http Laravel: // - GET запрос // - Авторизация Bearer с access token // - Доп. заголовок "x-api-key" с вашим ClientID $response = Http ::withHeaders([ 'x-api-key' => $clientID ]) ->withToken($token) ->get("https://pdf-services.adobe.io/operation/documentgeneration/{$requestID}/status"); $status = $response->json('status'); // Если статус не done, то либо ошибка, либо ещё формируется if ($status != 'done') { // Обработка ошибки } // Если всё успешно, то можно получить ID документа и ссылку на скачивание $assetID = $response->json('asset.assetID'); $downloadUri = $response->json('asset.downloadUri');
Документ сформирован и доступен по ссылке $downloadUri
Ссылки
ссылка на оригинал статьи https://habr.com/ru/post/708566/
Добавить комментарий