欢迎阅读面向开发人员的发票雷达插件手册!
本指南将帮助您创建自定义插件以从各种平台获取发票和收据。
发票雷达是一种文档自动化工具,可帮助您从各种平台获取、下载和组织发票和收据。
了解有关发票雷达的更多信息
介绍
入门
插件结构
编写你的第一个插件
有用的模式
步骤参考
JSON、HTML、CSS 和 JavaScript 的基本知识。
文本编辑器或 IDE(例如 VSCode、Sublime Text)。
安装在 macOS 或 Windows 上的发票雷达。
下载并安装发票雷达:
请求访问发票雷达
下载空白插件:
将空白插件下载到本地计算机。
将文件重命名为your-plugin-name.json
。
将其放入您选择的文件夹中。
将插件添加到发票雷达:
打开发票雷达。
导航到设置并选择Available Plugins
卡。
选择Choose Plugin Directory
并选择保存插件的文件夹。
您的插件现在应该出现在可用插件列表中。
发票雷达插件以 JSON 编写,并遵循特定的结构。每个插件由以下部分组成:
插件说明:
元数据:有关插件的基本信息,例如名称、描述和主页 URL。
configSchema :插件可能需要的配置属性。
刮痧步骤:
checkAuth :验证用户是否已通过身份验证的步骤。
startAuth :启动身份验证过程的步骤。
getDocuments :获取和下载文档的步骤。
{ "$schema": "https://raw.githubusercontent.com/invoiceradar/plugins/main/schema.json", "id": "示例", "名称": "示例平台", "描述": "服务的简短描述。", "homepage": "https://example.com", "checkAuth": [ {“action”:“导航”,“url”:“https://example.com/dashboard” }, {“action”:“checkElementExists”,“选择器”:“#logout-button” } ], "开始验证": [ {“action”:“导航”,“url”:“https://example.com/login” }, {“操作”:“waitForElement”,“选择器”:“#account-summary”,“超时”:120000 } ], "获取文档": [ {“action”:“导航”,“url”:“https://example.com/billing” }, { "action": "extractAll", "selector": ".invoice-row", "variable": "invoice", "fields": { "id": { "selector": ".invoice-id" }, "日期": { "选择器": ".发票日期" }, "总计": { "选择器": ".invoice-total" }, "url": { "selector": ".invoice-download", "attribute": "href" } }, "forEach": [ {“action”:“downloadPdf”,“url”:“{{invoice.url}}”,“文档”:“{{invoice}}” } ] } ] }
完整的架构可以在这里找到。
让我们创建一个简单的插件来从假设的服务中获取发票。
定义元数据:
此信息用于在发票雷达中识别和显示插件。主页 URL 用于获取服务的图标。
请注意, id
应该是唯一的且小写的。
{ "id": "example-service", "name": "示例服务", "description": "服务的简短描述。", "homepage": "https://example.com"}
了解有关元数据字段的更多信息。
定义配置架构(可选):
配置模式定义了插件运行所需的字段。在此示例中,我们需要teamID
和password
进行身份验证。
在发票雷达中添加插件时,这些字段将显示给用户。
"configSchema": { "teamID": { "type": "string", "title": "团队 ID", "description": "用于获取发票的团队或帐户的 ID。", "required": true } }
了解有关配置架构字段的更多信息。
检查身份验证:
checkAuth
包含验证用户是否经过身份验证的步骤。这可以通过检查 URL 或元素是否存在来完成。 checkAuth
中的最后一步需要是验证步骤。
这些步骤在运行开始时执行。如果用户已经通过身份验证,插件将跳过身份验证过程并直接获取文档。
“检查验证”:[ {“action”:“导航”,“url”:“https://example.com/dashboard” }, {“action”:“checkElementExists”,“选择器”:“#logout-button” } ]
开始认证:
startAuth
包含启动身份验证过程的步骤。这可能涉及导航到登录页面并等待成功登录指示符。
浏览器在身份验证过程中将可见,允许用户与登录表单进行交互。
“开始验证”:[ {“action”:“导航”,“url”:“https://example.com/login” }, {“操作”:“waitForElement”,“选择器”:“#account-summary”,“超时”:120000 } ]
抓取文档:
getDocuments
包含获取和下载文档的步骤。这可能涉及导航到计费页面、提取发票详细信息以及下载 PDF。
“获取文档”:[ {“action”:“导航”,“url”:“https://example.com/billing” }, { "action": "extractAll", "selector": ".invoice-row", "variable": "invoice", "fields": { "id": { "selector": ".invoice-id" }, "日期": { "选择器": ".发票日期" }, "总计": { "选择器": ".invoice-total" }, "url": { "selector": ".invoice-download", "attribute": "href" } }, "forEach": [ { "action": "downloadPdf", "url": "{{invoice.url}}", "document": { "type": "invoice", "id": "{{invoice.id}}", “日期”:“{{发票.日期}}”,“总计”:“{{发票.总计}}” } } ] } ]
你完成了! :
保存文件并将其添加到发票雷达。您现在可以运行该插件以从服务获取发票。
checkAuth
)如果用户未经身份验证,许多服务会自动重定向到登录页面。我们可以使用此行为来检查用户是否经过身份验证。
{ "action": "导航", "url": "https://example.com/login"}, {“action”:“checkURL”,“url”:“https://example.com/account”, }
根据服务的不同,如果您未经身份验证,他们可能会将您从仪表板重定向到登录页面。在这种情况下,您可以使用checkURL
步骤来检查访问仪表板后 URL 是否仍然匹配。
{ "action": "导航", "url": "https://example.com/dashboard"}, {“action”:“checkURL”,“url”:“https://example.com/dashboard”, }
请注意,您可以使用 glob 模式来匹配动态 URL: https://example.com/dashboard/**
。
您可以使用经过身份验证状态特有的选择器来检查用户是否经过身份验证,例如注销按钮或个人资料链接。
{ "action": "导航", "url": "https://example.com/home"}, {“action”:“waitForElement”,“selector”:“#logout-button”}
在某些情况下,执行checkElementExists
步骤时网站尚未完全加载。为了避免这种情况,您可以使用waitForNetworkIdle
属性来等待页面完全加载。
{“action”:“导航”,“url”:“https://example.com/home”,“waitForNetworkIdle”:true}, {“action”:“checkElementExists”,“selector”:“#logout-button”}
startAuth
)大多数身份验证过程都是从导航到登录页面并等待成功登录后出现特定元素开始的。
请记住,浏览器在身份验证过程中将可见,允许用户与登录表单进行交互。身份验证流程本身可以自动化,但这不是必需的。
{ "action": "导航", "url": "https://example.com/login"}, {“操作”:“waitForElement”,“选择器”:“#logout-button”,“超时”:120000}
为了给用户足够的时间登录,建议为等待步骤提供较长的超时时间,默认为 120 秒。
本节概述了可用于创建发票雷达插件的可用步骤。每个步骤代表可以在自动化过程中执行的特定操作。
导航步骤
导航( navigate
)
等待 URL ( waitForURL
)
等待元素 ( waitForElement
)
等待导航 ( waitForNavigation
)
等待网络空闲 ( waitForNetworkIdle
)
互动步骤
单击元素( click
)
输入文本( type
)
选择下拉菜单 ( dropdownSelect
)
运行 JavaScript ( runJs
)
验证步骤
检查元素是否存在 ( checkElementExists
)
检查网址 ( checkURL
)
运行 JavaScript ( runJs
)
数据提取步骤
提取物( extract
)
全部提取 ( extractAll
)
文件检索步骤
下载 PDF ( downloadPdf
)
等待 PDF 下载 ( waitForPdfDownload
)
将页面打印为 PDF ( printPdf
)
下载 Base64 PDF ( downloadBase64Pdf
)
条件逻辑步骤
如果( if
)
杂项步骤
睡觉( sleep
)
片段
从 Stripe URL 获取发票 ( getInvoiceFromStripeUrl
)
从 Stripe 客户门户获取发票 ( getInvoicesFromStripeBillingPortal
)
navigate
)导航到给定的 URL 并等待页面加载。默认情况下,它仅等待初始页面加载,而不等待任何后续 AJAX 请求。
{“action”:“导航”,“url”:“https://example.com”}
您可以将waitForNetworkIdle
设置为true
以确保页面已完全加载,然后再继续。
{“action”:“导航”,“url”:“https://example.com/dashboard”,“waitForNetworkIdle”:true}
很高兴知道:
支持相对 URL,并根据当前页面进行解析。
导航操作将仅等待初始页面加载,而不等待任何后续 AJAX 请求。
waitForURL
)等待当前 URL 与给定 URL 匹配,可以选择超时。支持通配符。
{“action”:“waitForURL”,“url”:“https://example.com/profile/**”,“超时”:3000}
waitForElement
)等待给定的选择器出现在页面上,可以选择超时。
{“操作”:“waitForElement”,“选择器”:“#example”,“超时”:3000}
waitForNavigation
)等待页面导航发生。此步骤不会等待页面完全加载。为此,请使用 waitForNetworkIdle 步骤。超时是可选的,默认为 10 秒
{“操作”:“waitForNavigation”,“超时”:10000}
waitForNetworkIdle
)等待网络空闲。如果您想确保页面已完成加载所有资源,这非常有用。当 500 毫秒内不再有网络请求时,这些步骤完成。超时是可选的,默认为 15 秒。
navigate
步骤有一个waitForNetworkIdle
选项,可以将其设置为true
以获得相同的行为。
{“操作”:“waitForNetworkIdle”,“超时”:10000}
click
)单击页面上给定选择器指定的元素。
{“操作”:“点击”,“选择器”:“#button”}
type
)将给定文本键入到页面上给定选择器指定的元素中。
{“操作”:“类型”,“选择器”:“#input”,“值”:“Hello World”}
dropdownSelect
)从页面上给定选择器指定的下拉列表中选择给定值。选择是基于选项的value
属性进行的。
{ "action": "dropdownSelect", "selector": "#dropdown", "value": "选项 1"}
runJs
)在页面上下文中运行给定的 JavaScript。如果承诺被返回,则将等待它。
如果您想在后续步骤中使用脚本的结果,请改用提取步骤。
{ "action": "runJs", "script": "document.querySelector('#example').click();"}
这些步骤在checkAuth
内部使用来验证用户是否已通过身份验证。
checkElementExists
)检查页面上是否存在给定的选择器。通常用于身份验证检查。
{“action”:“checkElementExists”,“选择器”:“#example”}
checkURL
)检查当前 URL 是否与给定 URL 匹配。支持通配符模式,例如https://example.com/dashboard/**
。
{“action”:“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": { "选择器”:“#team-link”,“属性”:“href” } } }
在此示例中, account
用作变量名称,并且使用 CSS 选择器提取字段id
、 name
和url
。它们可以在后续步骤中使用{{account.id}}
、 {{account.name}}
和{{account.url}}
占位符来使用。
使用 JavaScript:
{ "action": "extract", "variable": "token", "script": "localStorage.getItem('authToken')"}
此示例创建一个使用 JavaScript 提取的token
变量。可以使用{{token}}
占位符访问该值。也可以返回一个对象。
extractAll
)从页面中提取数据列表,并为每个项目运行给定的步骤。这通常用于迭代发票列表并下载它们。
对于与selector
匹配的每个元素,提取字段并将其存储在forEach
步骤中可用的variable
中。
很高兴知道:
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”:“导航”,“url”:“{{invoice.url}}” }, {“action”:“downloadPdf”,“发票”:“{{发票}}” } ] }
使用 JavaScript:
使用 JavaScript 时,结果应该是对象或值的数组。如果结果是一个承诺,我们就会等待。
{ "action": "extractAll", "script": "Array.from(document.querySelectorAll('#year-selector option')).map(option => option.value);", "variable": "年份”,“forEach”:[ {“action”:“dropdownSelect”,“selector”:“#year-selector”,“value”:“{{year}}” } ] }
分页
实验支持,尚未记录。
这些步骤用于下载文档并在发票雷达中处理它们。所有步骤都需要将document
对象作为参数传递,其中包含文档的元数据。
document
参数具有以下字段:
必需的
id
: 唯一的文档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" }
您可以单独传递每个字段,也可以传递整个对象(如果它包含所有必填字段)。
例如使用单独的字段:
“文档”:{ “id”:“{{item.invoiceId}}”,“日期”:“{{item.date}}”,“总计”:“{{item.amount}} {{item.currency” }}", "类型": "发票"}
例如,如果对象包含所有必填字段,您可以直接传递它:
“文档”:“{{项目}}”
downloadPdf
)从给定 URL 下载 PDF。
{“action”:“downloadPdf”,“url”:“https://example.com/invoice.pdf”,“文档”:{“id”:“{{item.invoiceId}}”,“日期”: “{{item.date}}”,“总计”:“{{item.total}}” } }
waitForPdfDownload
)等待 PDF 下载。超时默认为 15 秒。
{“action”:“waitForPdfDownload”,“超时”:10000,“文档”:{“id”:“{{item.invoiceId}}”,“日期”:“{{item.date}}”,“总计": "{{item.total}}" } }
printPdf
)将当前页面打印为 PDF 文件。
{ "action": "printPdf", "document": { "id": "{{item.invoiceId}}", "date": "{{item.date}}", "total": "{{item 。全部的}}” } }
downloadBase64Pdf
)从 Base64 编码字符串下载 PDF。
{“action”:“downloadBase64Pdf”,“base64”:“{{item.base64String}}”,“文档”:{“id”:“{{item.invoiceId}}”,“日期”:“{{item” .date}}", "总计": "{{item.total}}" } }
if
)如果条件为真,则运行给定步骤。如果条件为假,则执行else
步骤。
{ "action": "if", "script": "'{{invoice.url}}'.includes('pdf')", "then": [ {“操作”:“单击”,“选择器”:“#example” } ], “别的”: [ {“action”:“导航”,“url”:“https://example.com/fallback” } ] }
sleep
)等待给定的时间(以毫秒为单位)。一般不建议这样做。在大多数情况下,最好使用 waitForElement、waitForURL 或 waitForNetworkIdle 步骤。
{“行动”:“睡眠”,“持续时间”:1000}
片段是预先构建的步骤集,可简化常见任务。特定代码片段的步骤在开发人员工具中可见
目前,无法创建自定义片段。如果您认为作为代码片段有用的常见任务,请在 GitHub 上创建问题。
getInvoiceFromStripeUrl
)从 Stripe 发票 URL 中提取发票。
{“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()) ” “对于每个”:[ {“action”:“downloadPdf”,“url”:“{{invoice.url}}”,“文档”:{“id”:“{{invoice.id}}”,“日期”:“{{invoice” .date}}", "总计": "{{invoice.total}}" } } ] }
这将运行获取请求并将结果作为 JavaScript 对象返回。
内运行步骤在某些情况下,您可能需要在元素内运行一个步骤。为此,您可以在步骤上使用
iframe
属性。
{ "action": "点击", "选择器": "#button-inside-iframe", "iframe": true},
通过将iframe
设置为true
,发票雷达将找到页面上的第一个元素并运行其中的步骤。
您还可以使用 iframe 的src
属性中包含的字符串来定位特定的 iframe。
{ "action": "点击", "选择器": "#button-inside-iframe", "iframe": "iframe.example.com"},