Генерация файлов с Adobe

от автора

Мне поставили задачу: сформировать документ через Adobe API. Требований было минимум — главное сформировать документ из шаблона. Шаблон я мог отформатировать в нужный мне формат без проблем. Но сам формат, как его использовать и как это связать с API я не знал. Поэтому нырнул в документацию.

После пары часов изучения, я отчаялся. Информации было море, но нужной информации не нашел. Но зато нашел несколько вариантов документации, пару статей и несколько видео-уроков. Всё это не приблизило меня к цели ни на шаг.

Но спустя несколько дней, огромное количество нервов и желания сдаться, я всё-таки решил задачу. И буду рад поделиться решением тут.

Adobe Document Generation API

Первая задача: какой из Adobe сервисов нужен. 

Adobe Document Generation API. Он отвечает за генерацию, сжатие, конвертирование и иную работу с документами. Но нас интересует только генерация.

Чтобы его использовать, необходимо выполнить следующие шаги:

  1. Создать приложение

  2. Получить токен доступа (access token)

  3. Подготовить шаблон

  4. Загрузить шаблон

  5. Сформировать итоговый документ

Создаем приложение

Переходим по ссылке https://developer.adobe.com/console/projects, затем:

  1. Нажимаем «Create new Project»

  2. Нажимаем «Add to project» — выбираем API и ищем там PDF Services API

  3. Выбираем автоматическую генерацию приватных ключей, жмем «Continue» кучу раз

  4. Ждем пока 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *