Добро пожаловать в руководство по плагинам Invoice Radar для разработчиков!
Это руководство поможет вам создать собственные плагины для получения счетов и квитанций с различных платформ.
Invoice Radar — это инструмент автоматизации документов, который помогает вам получать, загружать и систематизировать счета и квитанции с различных платформ.
Узнайте больше о Invoice Radar
Введение
Начиная
Структура плагина
Написание вашего первого плагина
Полезные шаблоны
Справочник по шагам
Базовые знания JSON, HTML, CSS и JavaScript.
Текстовый редактор или IDE (например, VSCode, Sublime Text).
Invoice Radar установлен на macOS или Windows.
Загрузите и установите Invoice Radar :
Запросить доступ к Invoice Radar
Загрузите пустой плагин :
Загрузите пустой плагин на свой локальный компьютер.
Переименуйте файл в your-plugin-name.json
.
Поместите его в папку по вашему выбору.
Добавьте плагин в Invoice Radar :
Открыть радар счетов.
Перейдите к настройкам и выберите вкладку Available Plugins
.
Выберите Choose Plugin Directory
и выберите папку, в которой вы сохранили плагин.
Теперь ваш плагин должен появиться в списке доступных плагинов.
Плагины для Invoice Radar написаны в формате JSON и имеют определенную структуру. Каждый плагин состоит из следующих разделов:
Описание плагина :
Метаданные : основная информация о плагине, такая как имя, описание и URL-адрес домашней страницы.
configSchema : свойства конфигурации, которые могут потребоваться плагину.
Шаги очистки :
checkAuth : шаги для проверки того, прошел ли пользователь аутентификацию.
startAuth : шаги для запуска процесса аутентификации.
getDocuments : шаги для получения и загрузки документов.
{ "$schema": "https://raw.githubusercontent.com/invoiceradar/plugins/main/schema.json", "id": "example", "name": "Пример платформы", "description": " Краткое описание сервиса.", "homepage": "https://example.com", "checkAuth": [ { "действие": "навигация", "url": "https://example.com/dashboard" }, { "action": "checkElementExists", "selector": "#logout-button" } ], "startAuth": [ { "действие": "навигация", "url": "https://example.com/login" }, { "action": "waitForElement", "selector": "#account-summary", "timeout": 120000 } ], "получитьДокументы": [ { "действие": "навигация", "url": "https://example.com/billing" }, { "action": "extractAll", "selector": ".invoice-row", "variable": "invoice", "fields": { "id": { "selector": ".invoice-id" }, "date": { "selector": ".invoice-date" }, "total": { "selector": ".invoice-total" }, "url": { "селектор": ".invoice-download", "attribute": "href" } }, "forEach": [ { "action": "downloadPdf", "url": "{{invoice.url}}", "document": "{{invoice}}" } ] } ] }
Полную схему можно найти здесь.
Давайте создадим простой плагин для получения счетов от гипотетического сервиса.
Определите метаданные :
Эта информация используется для идентификации и отображения плагина в Invoice Radar. URL-адрес домашней страницы используется для получения значка службы.
Обратите внимание, что id
должен быть уникальным и записан в нижнем регистре.
{ "id": "example-service", "name": "Пример сервиса", "description": "Краткое описание сервиса", "homepage": "https://example.com"}
Узнайте больше о полях метаданных.
Определите схему конфигурации (необязательно):
Схема конфигурации определяет, какие поля необходимы для работы плагина. В этом примере для аутентификации нам нужен teamID
и password
.
Эти поля будут отображаться пользователю при добавлении плагина в Invoice Radar.
"configSchema": { "teamID": { "type": "string", "title": "ID команды", "description": "Идентификатор вашей команды или учетной записи для получения счетов.", "required": true } }
Узнайте больше о полях схемы конфигурации.
Проверьте аутентификацию :
checkAuth
содержит шаги для проверки подлинности пользователя. Это можно сделать, проверив URL-адрес или существование элемента. Последним шагом внутри checkAuth
должен быть шаг проверки.
Эти шаги выполняются при запуске цикла. Если пользователь уже прошел аутентификацию, плагин пропустит процесс аутентификации и перейдет непосредственно к получению документов.
"checkAuth": [ { "действие": "навигация", "url": "https://example.com/dashboard" }, { "action": "checkElementExists", "selector": "#logout-button" } ]
Начать аутентификацию :
startAuth
содержит шаги для инициации процесса аутентификации. Это может включать переход на страницу входа и ожидание индикатора успешного входа.
Браузер будет виден во время процесса аутентификации, что позволит пользователю взаимодействовать с формой входа.
"startAuth": [ { "действие": "навигация", "url": "https://example.com/login" }, { "action": "waitForElement", "selector": "#account-summary", "timeout": 120000 } ]
Очистить документы :
getDocuments
содержит шаги для получения и загрузки документов. Это может включать переход на страницу выставления счетов, извлечение сведений о счете и загрузку PDF-файлов.
"получитьДокументы": [ { "действие": "навигация", "url": "https://example.com/billing" }, { "action": "extractAll", "selector": ".invoice-row", "variable": "invoice", "fields": { "id": { "selector": ".invoice-id" }, "date": { "selector": ".invoice-date" }, "total": { "selector": ".invoice-total" }, "url": { "селектор": ".invoice-download", "attribute": "href" } }, "forEach": [ { "action": "downloadPdf", "url": "{{invoice.url}}", "document": { "type": "invoice", "id": "{{invoice.id}}", "date": "{{invoice.date}}", "total": "{{invoice.total}}" } } ] } ]
Готово! :
Сохраните файл и добавьте его в Invoice Radar. Теперь вы можете запустить плагин для получения счетов из сервиса.
checkAuth
)Многие службы автоматически перенаправляют на страницу входа, если пользователь не прошел аутентификацию. Мы можем использовать это поведение, чтобы проверить, аутентифицирован ли пользователь.
{ "действие": "навигация", "url": "https://example.com/login"}, { "action": "checkURL", "url": "https://example.com/account", }
В зависимости от службы они могут перенаправить вас с панели управления на страницу входа, если вы не прошли аутентификацию. В этом случае вы можете использовать шаг checkURL
, чтобы проверить, соответствует ли URL-адрес после посещения панели мониторинга.
{ "действие": "навигация", "url": "https://example.com/dashboard"}, { "action": "checkURL", "url": "https://example.com/dashboard", }
Обратите внимание, что вы можете использовать шаблоны glob для сопоставления динамических URL-адресов: https://example.com/dashboard/**
.
Вы можете использовать селектор, уникальный для состояния аутентификации, чтобы проверить, аутентифицирован ли пользователь, например кнопку выхода из системы или ссылку на профиль.
{ "действие": "навигация", "url": "https://example.com/home"}, { "action": "waitForElement", "selector": "#logout-button"}
В некоторых случаях веб-сайт загружается не полностью при выполнении шага checkElementExists
. Чтобы избежать этого, вы можете использовать атрибут waitForNetworkIdle
, чтобы дождаться полной загрузки страницы.
{ «действие»: «навигация», «url»: «https://example.com/home», «waitForNetworkIdle»: true}, { "action": "checkElementExists", "selector": "#logout-button"}
startAuth
)Большинство процессов аутентификации начинаются с перехода на страницу входа и ожидания появления определенного элемента после успешного входа в систему.
Помните, что браузер будет виден во время процесса аутентификации, что позволит пользователю взаимодействовать с формой входа. Сам процесс аутентификации можно автоматизировать, но это не обязательно.
{ "действие": "навигация", "url": "https://example.com/login"}, { "action": "waitForElement", "selector": "#logout-button", "timeout": 120000}
Чтобы дать пользователю достаточно времени для входа в систему, рекомендуется установить длительный таймаут для этапа ожидания, по умолчанию равный 120 секундам.
В этом разделе представлен обзор доступных шагов, которые можно использовать для создания плагинов для Invoice Radar. Каждый шаг представляет собой определенное действие, которое можно выполнить в процессе автоматизации.
Шаги навигации
Навигация ( navigate
)
Дождитесь URL-адреса ( waitForURL
)
Дождитесь элемента ( waitForElement
)
Ожидание навигации ( waitForNavigation
)
Дождитесь простоя сети ( waitForNetworkIdle
)
Этапы взаимодействия
Нажмите «Элемент» ( click
)
Введите текст ( type
)
Выберите раскрывающийся список ( dropdownSelect
)
Запустите JavaScript ( runJs
)
Этапы проверки
Проверить существование элемента ( checkElementExists
)
Проверить URL ( checkURL
)
Запустите JavaScript ( runJs
)
Этапы извлечения данных
Экстракт ( extract
)
Извлечь все ( extractAll
)
Этапы получения документа
Скачать PDF ( downloadPdf
)
Подождите загрузки PDF ( waitForPdfDownload
)
Распечатать страницу в формате PDF ( printPdf
)
Скачать Base64 PDF ( downloadBase64Pdf
)
Условные логические шаги
Если ( if
)
Разные шаги
Спать ( sleep
)
Фрагменты
Получить счет из URL-адреса Stripe ( getInvoiceFromStripeUrl
)
Получение счетов с клиентского портала Stripe ( getInvoicesFromStripeBillingPortal
)
navigate
)Переходит по указанному URL-адресу и ожидает загрузки страницы. По умолчанию он ожидает только начальной загрузки страницы, а не последующих запросов AJAX.
{ "действие": "навигация", "url": "https://example.com"}
Вы можете установить для waitForNetworkIdle
значение true
, чтобы убедиться, что страница полностью загружена, прежде чем продолжить.
{ «действие»: «навигация», «url»: «https://example.com/dashboard», «waitForNetworkIdle»: true}
Полезно знать :
Относительные URL-адреса поддерживаются и будут разрешены на основе текущей страницы.
Действие навигации будет ожидать только начальной загрузки страницы, а не последующих запросов AJAX.
waitForURL
)Ожидает совпадения текущего URL-адреса с заданным URL-адресом (необязательно с тайм-аутом). Поддерживает подстановочные знаки.
{ "action": "waitForURL", "url": "https://example.com/profile/**", "timeout": 3000}
waitForElement
)Ожидает появления данного селектора на странице, возможно с таймаутом.
{ "action": "waitForElement", "selector": "#example", "timeout": 3000}
waitForNavigation
)Ожидает, пока произойдет навигация по странице. Этот шаг не будет ждать полной загрузки страницы. Для этой цели используйте шаг waitForNetworkIdle. Таймаут не является обязательным и по умолчанию равен 10 секундам.
{ "action": "waitForNavigation", "timeout": 10000}
waitForNetworkIdle
)Ожидает, пока сеть станет бездействующей. Это полезно, если вы хотите убедиться, что страница завершила загрузку всех ресурсов. Шаг завершается, когда в течение 500 мс больше не поступает сетевых запросов. Таймаут не является обязательным и по умолчанию равен 15 секундам.
Шаг navigate
имеет параметр waitForNetworkIdle
, для которого можно установить значение true
чтобы получить такое же поведение.
{ "действие": "waitForNetworkIdle", "тайм-аут": 10000}
click
)Щелкает элемент, указанный данным селектором на странице.
{ "action": "click", "selector": "#button"}
type
)Вводит заданный текст в элемент, указанный данным селектором на странице.
{ "action": "type", "selector": "#input", "value": "Hello World"}
dropdownSelect
) Выбирает заданное значение из раскрывающегося списка, указанного данным селектором на странице. Выбор происходит на основе атрибута value
опции.
{ "action": "dropdownSelect", "selector": "#dropdown", "value": "Option 1"}
runJs
)Запускает указанный JavaScript в контексте страницы. Если обещание возвращается, оно будет ожидаемо.
Если вы хотите использовать результат сценария на последующих шагах, используйте вместо этого шаг извлечения.
{ "action": "runJs", "script": "document.querySelector('#example').click();"}
Эти шаги используются внутри checkAuth
для проверки подлинности пользователя.
checkElementExists
)Проверяет, существует ли данный селектор на странице. Обычно используется для проверки подлинности.
{ "action": "checkElementExists", "селектор": "#example"}
checkURL
) Проверяет, соответствует ли текущий URL-адрес заданному URL-адресу. Поддерживает шаблоны подстановочных знаков, такие как https://example.com/dashboard/**
.
{ "действие": "checkURL", "url": "https://example.com"}
runJs
) Шаг runJs
также можно использовать в качестве шага проверки. Запустив сценарий, который возвращает истинное или ложное значение, вы можете проверить, аутентифицирован ли пользователь.
{ "action": "runJs", "script": "document.cookie.includes('authToken');"}
Эти шаги используются для загрузки данных со страницы, например списка элементов или одного значения, и использования их на последующих шагах.
extract
)Извлекает один фрагмент данных со страницы и сохраняет его в переменной.
Использование полей CSS:
{ "action": "extract", "variable": "account", "fields": { "id": "#team-id", "name": "#team-name", "url": { " selector": "#team-link", "attribute": "href" } } }
В этом примере account
используется в качестве имени переменной, а поля id
, name
и url
извлекаются с помощью селекторов CSS. Их можно использовать на последующих шагах, используя заполнители {{account.id}}
, {{account.name}}
и {{account.url}}
.
Использование JavaScript:
{ "действие": "извлечение", "переменная": "токен", "скрипт": "localStorage.getItem('authToken')"}
В этом примере создается переменная token
, которая извлекается с помощью JavaScript. Доступ к значению можно получить с помощью заполнителя {{token}}
. Также возможно вернуть объект.
extractAll
)Извлекает список данных со страницы и выполняет заданные шаги для каждого элемента. Обычно это используется для перебора списка счетов-фактур и их загрузки.
Для каждого элемента, соответствующего selector
, поля извлекаются и сохраняются в variable
доступной на шагах forEach
.
Полезно знать :
Каждый селектор внутри объекта fields
автоматически ограничивается соответствующим элементом.
Поле variable
является необязательным. Если не указано иное, извлеченные данные будут сохранены в переменной item
по умолчанию.
Доступ к текущему индексу можно получить с помощью заполнителя {{index}}
. Он начинается с 0 и увеличивается для каждого элемента.
С полями CSS:
{ "action": "extractAll", "selector": ".invoice-list .invoice-item", "variable": "invoice", "fields": { "id": "td.invoice-id", " date": "td.invoice-date", "total": "td.invoice-total", "url": { "selector": "a.invoice-link", "attribute": "href" } }, "forEach": [ { "action": "navigate", "url": "{{invoice.url}}" }, { "action": "downloadPdf", "invoice": "{{invoice}}" } ] }
С помощью JavaScript:
При использовании JavaScript результатом должен быть массив объектов или значений. Если результат обещан, его будут ждать.
{ "action": "extractAll", "script": "Array.from(document.querySelectorAll('#year-selector option')).map(option => option.value);", "variable": "year ", "дляКаждый": [ { "action": "dropdownSelect", "selector": "#year-selector", "value": "{{year}}" } ] }
Пагинация
Экспериментальная поддержка, еще не документированная.
Эти шаги используются для загрузки документов и их обработки в Invoice Radar. Все шаги требуют, чтобы объект document
был передан в качестве аргумента, который содержит метаданные документа.
Аргумент document
имеет следующие поля:
Необходимый
id
: уникальный идентификатор документа.
Например, INV-123
или 123456
date
: дата счета в виде строки.
Например 2022-01-01
или 01/01/2022
или January 1, 2022
Рекомендуется
total
: общая сумма счета, включая валюту.
Например $100.00
или €100.00
, или 100 EUR
, или 100,00€
Встроенный анализатор попытается извлечь сумму и валюту из строки.
Необязательный
type
: тип документа (необязательно. По умолчанию — auto
).
Может быть установлен на auto
, invoice
, receipt
, refund
или other
.
metadata
: дополнительные метаданные для документа (необязательно).
Например { "orderNumber": "12345" }
Вы можете передать каждое поле отдельно или весь объект, если он содержит все обязательные поля.
Например, используя отдельные поля:
"document": { "id": "{{item.invoiceId}}", "date": "{{item.date}}", "total": "{{item.amount}} {{item.currency }}", "type": "счет"}
Например, если объект содержит все обязательные поля, вы можете передать его напрямую:
"document": "{{item}}"
downloadPdf
)Загружает PDF-файл с указанного URL-адреса.
{ "action": "downloadPdf", "url": "https://example.com/invoice.pdf", "document": { "id": "{{item.invoiceId}}", "date": "{{item.date}}", "total": "{{item.total}}" } }
waitForPdfDownload
)Ожидает загрузки PDF. Таймаут по умолчанию равен 15 секундам.
{ "action": "waitForPdfDownload", "timeout": 10000, "document": { "id": "{{item.invoiceId}}", "date": "{{item.date}}", "total ": "{{item.total}}" } }
printPdf
)Печатает текущую страницу в файл PDF.
{ "action": "printPdf", "document": { "id": "{{item.invoiceId}}", "date": "{{item.date}}", "total": "{{item .общий}}" } }
downloadBase64Pdf
)Загружает PDF-файл из строки в кодировке Base64.
{ "action": "downloadBase64Pdf", "base64": "{{item.base64String}}", "document": { "id": "{{item.invoiceId}}", "date": "{{item .date}}", "total": "{{item.total}}" } }
if
) Выполняет указанные шаги, если условие истинно. Если условие ложно, выполняются else
шаги.
{ "action": "if", "script": "'{{invoice.url}}'.includes('pdf')", "then": [ { "action": "click", "selector": "#example" } ], "еще": [ { "action": "навигация", "url": "https://example.com/fallback" } ] }
sleep
)Ожидает заданное количество времени в миллисекундах. Обычно это не рекомендуется. В большинстве случаев лучше использовать шаги waitForElement, waitForURL или waitForNetworkIdle.
{ "действие": "сон", "продолжительность": 1000}
Сниппеты — это готовые наборы шагов, которые упрощают общие задачи. Шаги для конкретного фрагмента видны в инструментах разработчика.
В настоящее время невозможно создавать собственные фрагменты. Если у вас есть общая задача, которую, по вашему мнению, можно было бы использовать в виде фрагмента, создайте задачу на GitHub.
getInvoiceFromStripeUrl
)Извлекает счет из URL-адреса счета Stripe.
{ "action": "runSnippet", "snippet": "getInvoiceFromStripeUrl", "args": { "url": "https://invoice.stripe.com/i/inv_123" } }
getInvoicesFromStripeBillingPortal
)Извлекает доступные счета с биллингового портала Stripe.
{ "action": "runSnippet", "snippet": "getInvoicesFromStripeBillingPortal", "args": { "url": "https://stripe-portal.example.com/billing" } }
Иногда вам может потребоваться выполнить запрос на выборку внутри шага для получения данных из API. Для этого вы можете использовать действие extractAll
.
{ "action": "extractAll", "variable": "invoice", "script": "fetch('https://example.com/api/invoices').then(res => res.json()) " "forEach": [ { "action": "downloadPdf", "url": "{{invoice.url}}", "document": { "id": "{{invoice.id}}", "date": "{{invoice .date}}", "total": "{{invoice.total}}" } } ] }
Это запустит запрос на выборку и вернет результат в виде объекта JavaScript.
В некоторых сценариях вам может потребоваться выполнить шаг внутри элемента . Для этого вы можете использовать атрибут
iframe
на шаге.
{ "action": "click", "selector": "#button-inside-iframe", "iframe": true},
Установив для iframe
значение true
, Invoice Radar найдет первый элемент на странице и выполнит шаг внутри него.
Вы также можете использовать строку, содержащуюся внутри атрибута src
iframe, для нацеливания на определенный iframe.
{ "action": "click", "selector": "#button-inside-iframe", "iframe": "iframe.example.com"},