Automatisch 内置 Formatter 应用详解:无需连接即可完成文本、数字与日期时间的数据格式化
2026/9/15 20:14:06 网站建设 项目流程

Automatisch 内置 Formatter 应用详解:无需连接即可完成文本、数字与日期时间的数据格式化

【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch

Formatter 是 Automatisch 中随发行版内置的"零连接"应用,它不依赖任何外部服务,无需配置凭据即可在流程中充当动作节点,对上游步骤产生的数据进行文本、数字与日期时间的清洗与转换。读完本文,你将掌握 Formatter 全部三大类转换能力的适用场景、参数含义与源码级实现原理,并能在自己的自动化流程中直接落地使用。

Formatter 为什么不需要"连接"

在 Automatisch 中,大多数应用(如 GitHub、Slack、Gmail)都要求先建立 Connection 才能被流程引用。Formatter 则完全不同:官方文档明确指出它是 built-in app,运行时不与任何外部服务通信,因此没有任何额外的连接步骤

这一点在源码中得到了直接印证。应用注册文件 packages/backend/src/apps/formatter/index.js 中有如下关键声明:

export default defineApp({ name: 'Formatter', key: 'formatter', iconUrl: '{BASE_URL}/apps/formatter/assets/favicon.svg', authDocUrl: '{DOCS_URL}/apps/formatter/connection', supportsConnections: false, // 关键:不需要任何连接 baseUrl: '', apiBaseUrl: '', primaryColor: '#001F52', actions, dynamicFields, });

其中supportsConnections: false意味着在流程编辑器中选中 Formatter 时,不会出现"选择连接"的步骤,可以直接配置动作参数。它只能作为**动作(Action)**使用,不能作为触发器(Trigger)——因为它本身不产生新事件,其职责是消费并改造上游数据,再把结果交给下游步骤。

在流程中添加 Formatter 动作

在流程编辑器中添加动作节点后,搜索并选择 Formatter,即可看到三大类动作。这三大类在 动作聚合入口 中注册为textnumbersdateTime三个动作:

动作key能力摘要
Texttext大小写、HTML/Markdown 互转、抽取邮箱与数字、复数化、替换、去空白、默认值等
Numbersnumbers数学运算、随机数、数字格式化
Date / Timedate-time日期时间格式化、当前时间戳

每个动作的配置界面都由一个必选的Transform下拉框驱动。当你选择某个具体转换项后,表单会自动加载该项对应的参数(这是通过动态字段机制实现的,下文会展开),例如选择 "Replace" 后才会出现FindReplace输入框。这意味着你只需要为当前选中的转换填写必要的参数,无需理解其他无关选项。

Text 文本类转换详解

官方文档列出的文本类能力共 10 项,全部位于 actions/text 目录。除此之外,当前仓库源码还额外实现了 6 个转换项(Base64 互转、URI 编码、UUID、JSON 解析),合计 16 个,下面逐一说明。

1. Capitalize(首字母大写)

把输入文本中每个单词的首字母转为大写、其余字母转为小写。实现位于 capitalize.js,它借助 lodash 的capitalize配合正则/\w+/g逐词处理:

const capitalizedInput = input.replace(/\w+/g, lodashCapitalize);

例如输入hello world会得到Hello World,适用于对人名、标题、品牌词做规范化。

2. Convert HTML to Markdown(HTML 转 Markdown)

将一段 HTML 字符串转换为 Markdown 文本,实现见 html-to-markdown.js,底层使用node-html-markdown库的NodeHtmlMarkdown.translate(input)。当你从网页抓取、RSS 摘要等来源拿到 HTML 片段,需要写入支持 Markdown 的目标应用(如 Notion、Discord)时非常有用。

3. Convert Markdown to HTML(Markdown 转 HTML)

反向转换:把 Markdown 渲染为 HTML,实现见 markdown-to-html.js,底层使用showdown库的Converter().makeHtml(input)。适合把面向编辑的 Markdown 内容转成富文本 / 邮件正文场景。

4. Extract Email Address(抽取邮箱地址)

从一段自由文本中抽取第一个匹配的邮箱地址,实现见 extract-email-address.js,核心是标准邮箱正则:

const emailRegexp = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:a-z0-9?\.)+a-z0-9?/; const email = input.match(emailRegexp); return email ? email[0] : '';

注意:无匹配时返回空字符串而非报错,可安全用于后续步骤;若需要提取多个邮箱,可从该实现逻辑推断当前版本只返回第一个匹配项。

5. Extract Number(抽取数字)

从文本中抽取第一个数字串,实现见 extract-number.js,其注释明确列出了一系列支持的数字形态,包括123-123121,234-121.2341,234,567.89-1.234.567,89等千分位与小数分隔符组合,匹配正则如下:

const numberRegexp = /-?((\d{1,3})+\.?,?)+/g; const numbers = input.match(numberRegexp); return numbers ? numbers[0] : '';

例如从"总金额为 1,234,567.89 元"中可抽出1,234,567.89

6. Lowercase(转小写)

将输入文本全部转为小写。适合对关键词、标签、邮箱地址等做归一化处理,避免因大小写不一致导致后续匹配失败。对应入口定义见 text/index.js。

7. Pluralize(复数化)

将英文单词转换为复数形式,实现见 pluralize.js,底层使用pluralize库。例如"apple""apples""person""people"。适合在生成报表文案、通知消息时动态构造正确语法。

8. Replace(文本替换)

在输入文本中查找并替换内容,实现见 replace.js。它有两个重要能力:

  • 普通替换input.replaceAll(find, replace),替换所有出现的位置;
  • 正则替换:开启useRegex后使用new RegExp(find, flags)构造表达式,并支持ignoreCase忽略大小写,最终同样执行replaceAll

值得关注的是源码中的一道安全保护(replace.js):正则模式会先设置一个 100ms 的定时器,若正则执行(如灾难性回溯)导致超时,会通过$.execution.exit()提前终止执行,避免正则表达式长时间阻塞流程运行:

const timeoutId = setTimeout(() => { $.execution.exit(); }, 100); const regex = new RegExp(find, flags); const replacedValue = input.replaceAll(regex, replace); clearTimeout(timeoutId);

对应参数定义在动态字段 list-transform-options/text/replace.js 中:Input(必填)、Find(必填)、Replace(可选,替换为空即删除)、Use Regular Expression(下拉 Yes/No,选择 Yes 后会动态追加忽略大小写选项)。注意:若要使用捕获组引用等能力,应直接编写完整正则。

9. Trim Whitespace(去除首尾空白)

去除输入文本两端的空白字符(空格、制表符、换行等)。适合清洗从表单、表格或外部 API 取回的用户输入,避免多余空白影响后续的匹配、比较或入库。入口定义见 text/index.js。

10. Use Default Value(空值兜底)

当输入为空或仅为空白时,返回预设的默认值,实现见 use-default-value.js:

if (input && input.trim().length > 0) { return input; } return $.step.parameters.defaultValue;

这是典型的"数据管道兜底"模式:上游字段可能缺失或为空,用它可以在流程早期把空值替换为可预期的默认值,防止下游步骤因空值而失败或产生错误分支。

11~16. 仓库额外实现的文本转换

除文档列出的 10 项外,当前源码还注册了以下 6 项(见 text/index.js 的 options 列表):

  • Base64 to String/String to Base64:字符串与 Base64 编码互转(base64-to-string.js、string-to-base64.js),适合处理带附件的邮件内容、API 返回的编码数据;
  • Create UUID:生成 UUID(create-uuid.js),可用于为记录生成唯一标识;
  • Encode URI/Encode URI Component:分别对应encodeURIencodeURIComponent(encode-uri.js、encode-uri-component.js),构造 URL 参数或拼接请求地址时常用;
  • Parse stringified JSON:解析字符串形式的 JSON(parse-stringified-json.js),把上游返回的 JSON 字符串变成结构化数据供后续步骤引用。

Numbers 数字类转换详解

数字类动作位于 actions/numbers,官方文档列出 3 项,仓库中还包含第 4 项"格式化电话号码"。

1. Perform Math Operation(数学运算)

对一组数值执行指定运算,实现见 perform-math-operation.js,内部把每个输入值Number()化后通过 lodash 方法规约计算:

运算行为
add累加,初始值 0
subtract依次相减(按输入顺序从第一个开始减去后续值)
multiply连乘,初始值 1
divide依次相除(注意除数为 0 时结果为Infinity
modulo依次取余
makeNegative对每个值取相反数,返回数组

适用于计算订单小计、批量金额汇总、折扣后价格等场景。多个数值通过values列表传入,每个元素为{ input: ... }结构(源码中values.map((value) => Number(value.input))体现了这一点)。

2. Random Number(随机数)

在指定范围内生成随机数,实现见 random-number.js:

const lowerRange = Number($.step.parameters.lowerRange); const upperRange = Number($.step.parameters.upperRange); const decimalPoints = Number($.step.parameters.decimalPoints) || 0; return Number( (Math.random() * (upperRange - lowerRange) + lowerRange).toFixed(decimalPoints) );

参数为Lower RangeUpper Range(闭区间采样)和可选的Decimal Points(小数位数,默认 0)。可用于抽奖、AB 分流、生成临时验证码等场景。注意随机范围默认不校验上下界大小关系,使用时请自行保证upperRange >= lowerRange

3. Format Number(数字格式化)

将数字按指定的千分位 / 小数分隔符风格输出,实现见 format-number.js,底层使用accounting库,并自动根据输入值的小数位数保留精度:

To Format取值千分位分组符小数点
0逗号,句点.(如1,234,567.89
1句点.逗号,(如1.234.567,89
2空格句点.(如1 234 567.89
3空格逗号,(如1 234 567,89

使用时可指定Input Decimal Mark说明输入数字使用的小数点符号,配合To Format实现跨地区数字格式互转,比如把美国格式1,234,567.89转为欧洲格式1.234.567,89

4. Format Phone Number(格式化电话号码)

对手机号进行格式化输出,实现见 format-phone-number.js,国家码选项来自 common/phone-number-country-codes.js。适合在发送短信(如 Twilio、SignalWire、Telegram)或写入 CRM 前统一号码显示格式。

Date / Time 日期时间类转换详解

日期时间类动作位于 actions/date-time,官方文档列出 1 项,仓库中另外提供 2 个时间戳获取转换项。

1. Format Date / Time(日期时间格式化)

对既有时间值做格式与时区的双重转换,实现见 format-date-time.js,底层使用luxon库。需要配置 5 个参数(定义见 dynamic-fields 中的 format-date-time.js):

参数是否必填说明
Input要格式化的原始时间字符串(支持变量引用上游数据)
From Format输入时间的格式,使用 Luxon 格式令牌
From Timezone输入时间所在的时区(如Asia/Shanghai
To Format输出时间的格式
To Timezone输出目标时区

源码中还有一个容易被忽略的细节:当From FormatX时,输入被当作秒级 Unix 时间戳DateTime.fromSeconds(Number(input)));为x时被当作毫秒级时间戳DateTime.fromMillis(Number(input)))。也就是说,直接粘贴1700000000这样的秒级时间戳也能正确解析,无需先转成字符串日期。核心转换逻辑如下:

const outputDateTime = inputDateTime.setZone(toTimezone).toFormat(toFormat);

时区选项取自Intl.supportedValuesOf('timeZone')的全量列表(见 options/timezone.js),覆盖全球各大时区。典型场景是把外部 API 返回的 UTC 时间统一转换为业务所在地时间,例如从2024-01-15T08:00:00.000Z(UTC)转为2024-01-15 16:00(Asia/Shanghai)。

2. 获取当前时间戳(两个变体)

  • Get current timestamp:返回毫秒级 Unix 时间戳(get-current-timestamp.js);
  • Get current timestamp in seconds:返回秒级 Unix 时间戳(get-current-timestamp-in-seconds.js)。

两个转换项不需要任何参数,可用于为记录打时间戳、构造签名参数、或作为流程排他去重的依据。

转换分发的底层机制:Transformer 与动态字段

理解 Formatter 的源码结构,有助于你预判每个转换项的行为:

  1. 统一分发:三个动作(text / numbers / date-time)的run方法完全同构,都以$.step.parameters.transform为 key,从各自的 transformers 映射表中取出对应函数并执行,再通过$.setActionItem({ raw: { output } })把结果写入执行记录。以 Text 为例见 text/index.js 的 run 方法。这意味着每个转换项本质都是一个纯函数:输入来自$.step.parameters,输出即动作结果。

  2. 动态字段:Formatter 的每个动作都声明了additionalFieldsgetDynamicFields+listTransformOptions),当Transform下拉框的值变化时,后端动态字段接口会根据该值返回对应的参数字段列表。因此不同转换项的参数字段是按需加载的,这也是为什么你在界面上只会看到当前转换所需的输入框。相关实现位于 dynamic-fields/list-transform-options 目录,与 transformers 一一对应。

  3. 无连接、无触发器:从应用注册的supportsConnections: false与仅注册actions两个特征可以确认,Formatter 只能作为动作节点插入到已有触发器(如 Webhook、Scheduler、表单提交)之后,作为数据管道的中间处理环节。

实战使用建议

  • 数据管道中放中间:把 Formatter 动作放在"数据来源步骤"与"目标应用动作"之间,先清洗再入库,可显著减少下游因脏数据导致的执行失败。
  • 组合使用:例如 RSS 抓取的文章 HTML →Convert HTML to MarkdownReplace清理冗余片段 → 写入 Notion / Discord;或表单邮箱字段 →Trim Whitespace+Lowercase→ 查询 CRM。
  • 注意空值语义Extract Email AddressExtract Number在无匹配时返回空字符串而非报错,若希望空值时走默认值分支,可再接一个Use Default Value转换。
  • 正则替换的边界:Replace 的正则模式会全局匹配(flags 含g)并受 100ms 超时保护;超长或高回溯复杂度的正则仍建议先在本地验证。

结语

Formatter 用最少的配置成本解决了自动化流程中最常见的数据整形需求:文本清洗、数字运算、日期时间与时区转换一应俱全,且完全离线运行、无外部依赖。结合 官方动作列表文档 与仓库源码(应用注册见 index.js,转换实现见 actions 目录),你可以随时查阅每个转换项的参数定义与实现细节,把这条"免连接"的格式化链路熟练地嵌入你的 Automatisch 工作流中。

【免费下载链接】automatischThe open source Zapier alternative. Build workflow automation without spending time and money.项目地址: https://gitcode.com/GitHub_Trending/au/automatisch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询