# 探秘Web2中的IFTTT与Web3中的Drippie: 底层原理解析与对比

By [Yooma](https://paragraph.com/@yooma) · 2023-04-14

---

导语
--

IFTTT和Drippie都是用于自动化任务的工具，实现如果这样(this) 那就那样(that) 的需求。IFTTT已经发展了许多年，而Drippie是新生的产品。他们目标是一致的，但是实现的技术以及面向的对象有所区别，接下来看一看成熟的IFTTT和 新生的Web3 IFTTT——Drippie

IFTTT
-----

### 介绍

IFTTT (If This Then That) 是一款服务，提供了一种简单的方式来**自动化**各种日常任务。通过 IFTTT，用户可以将不同的应用程序和服务连接起来，然后创建称为“**Applets**”(也可以叫做**_Recipes_**)的自动化规则，使得在一个应用程序中发生的事件能够自动地触发另一个应用程序的响应。例如，用户可以创建一个Applets：如果他们的Twitter收到消息，那么就把这个消息发送到他们Gmaill。

### 实现

由于IFTTT集成了许多第三方服务，也会存在大量的Applets，那么对于数据的处理架构就需要非常完善严谨。

**数据处理的基础架构：**

![](https://storage.googleapis.com/papyrus_images/09115b48d2b16241a94272e88db79f10b0c27a0dfbdc7bafaaa2f94ef0932fc6.png)

1.  **AWS Data Pipeline**：AWS Data Pipeline 是一种**自动化的 ETL**（Extract, Transform, Load）服务，它可以让用户在 AWS 云上轻松地从各种数据源中**提取、转换和加载**数据。IFTTT使用Data Pipeline来将数据从不同的数据源中提取然后将结果存储在AWS Redshift、AWS RDS等目标数据存储中，供后续的分析和可视化使用。
    
2.  **AWS Redshift**：Amazon Redshift 是一种**高性能**的云数据仓库服务，它可以大规模地处理和分析数据。IFTTT使用Redshift来存储和分析**用户数据和事件**数据。
    
3.  **Chartio**：Chartio 是一种云 BI（Business Intelligence）工具，它可以连接各种数据源，并提供交互式的**数据可视化和报表**功能。IFTTT使用Chartio来创建和共享数据报表和仪表板更好地理解其数据。
    
4.  **Kafka**：Apache Kafka是一种分布式流处理平台，用于**处理高速数据流**。IFTTT使用Kafka作为事件流处理引擎，以支持**实时事件处理和数据**分析。
    
5.  **AWS S3**：Amazon Simple Storage Service（S3）是一种**面向对象的存储**服务，它可以让用户在云中存储和检索任意数量的数据对象。例如执行的日志、_Recipes_的输入和输出、触发器数据等。
    
6.  **Cranium ETL**：Cranium ETL 是一种开源的 ETL 工具，它可以帮助用户从各种数据源中**提取、转换和加载**数据。IFTTT使用Cranium ETL来**自动化数据清理和预处理**。
    
7.  **Spark**：Apache Spark 是一种快速、通用、可扩展的分布式**计算引擎**，它支持大规模**数据处理**和**机器学习**等任务。IFTTT使用Spark来确保IFTTT用户有良好的体验
    
8.  **Recipe Worker**：Recipe Worker 是一个用于**执行** Recipes 的服务，它是整个 IFTTT 系统的**核心部分**之一。当一个 Recipe 被创建或更新时，IFTTT 的服务器会将该 Recipe 发送到 Recipe Worker，Recipe Worker 会按照指定的触发器和动作，从不同的数据源中获取数据并执行相应的操作。因此，Recipe Worker 是一个高度可扩展的系统。
    
9.  **Partner APIs**：Partner APIs 是 IFTTT 用于**与第三方服务进行集成**的接口。通过与其他公司的 API 集成，IFTTT 可以在其平台上创建更多的 Recipes，并提供更多的服务。IFTTT 的合作伙伴可以通过 Partner APIs 来访问 IFTTT 平台，并提供他们自己的触发器和动作，以及其他的功能。
    
10.  **Elasticsearch**：Elasticsearch是一种分布式**搜索和分析**引擎，可用于实时搜索、日志分析、安全分析等。IFTTT使用Elasticsearch作为日志分析引擎，以支持日志分析和异常检测。
    
11.  **Internal Monitoring Alerting**：Internal Monitoring Alerting 是 IFTTT 用于**监控**其整个系统的**服务**。这个服务通过定期检查 IFTTT 的各个组件的性能和可用性来确保系统的正常运行。当系统出现问题时，Internal Monitoring Alerting 会向 IFTTT 的运维人员发送警报，以便他们可以采取相应的措施来解决问题。
    

在IFTTT有三种数据来源，对于理解用户的行为和Channels的效率至关重要。

第一，在 AWS RDS 有一个 MySQL 集群，用来维护应用的基本内容的当前状态，比如用户、Channels和Recipes，包括他们的关系。IFTTT.com 和移动应用靠**Rails应用**(_支持 IFTTT 网站和移动应用的后端程序_)支撑。获得数据并导入到S3，然后用AWS Data Pipline导入到Redshift。

接下来，像用户与 IFTTT 产品的**交互数据**，从Rails应用里收集事件数据到Kafka集群。

最后，为了帮助监控数以千计的合作伙伴 **API 的行为**，IFTTT收集在运行 Recipes 时 workers 产生的 API 请求的信息，包括响应时间和HTTP状态码，都导入到Kafka集群。

使用Kafka做数据传输层，**实现数据生产者和消费者之间的解耦**。这种架构中，Kafka在系统中作为生产者和消费者之间的一种抽象层，而不是数据直接推向消费者。生产者将数据推送到Kafka，消费者从Kafka中读数据。这使得添加新数据消费者更松散。

Kafka是一种基于日志的事件流，它可以跟踪消费者在事件流中的位置，因此消费者可以**实时或批量地处理数据**，并且可以重新处理之前已经消费过的数据。这为数据处理提供了更大的灵活性和可靠性。

一旦数据进入Kafka中，就可以应用于多种不同的场景。例如：批量数据的消费者可以将数据的副本分批存储到S3中，以便后续使用。另一方面，实时数据的消费者则可以将数据传输到Elasticsearch集群中，以实现实时的数据查询和分析。

用Cranium（内部ETL平台）将S3中数据变换和归一化后导入到AWS Redshift。通过Cranium能够用SQL和Ruby编写ETL任务，它定义了这些任务之间的依赖和安排他们执行。Cranium支持**数据可视化**报告（利用Ruby和D3），但是大多数数据可视化是用**Chartio**。

无论是工程中还是业务中甚至是社区中人们都可以利用这些数据来解决问题，发现新的点。

并且采用一些先进的**机器学习技术**来确保IFTTT用户有良好的体验。对于Recipe的推荐和滥用检测，IFTTT用在EC2上的运行Apache Spark，用S3作数据存储。

API 事件存储在 Elasticsearch 中，来进行**实时监控**和报警。并使用Kibana来**可视化**worker进程的实时性能和合作伙伴的API性能。

IFTTT的合作伙伴访问Developer Channel（当他们的API有问题时触发这个Channel）。可以用Developer Channel 创建Recipes，可选择不同的方式（SMS，Email，Slack等）来通知合作伙伴们。

在开发者dashboard，合作伙伴可以访问实时日志和可视化他们的Channel健康状况。 用Elasticsearch来实现比较好。此外，提供给开发者强大的分析能力帮开发者们了解谁在使用他们的Channel以及如何使用的。

### 工作流程举例：

1.  用户在IFTTT官网上创建一个Applet，其中包括两个触发器（Trigger）：一个是Twitter消息触发器，另一个是Gmail消息触发器。用户还需要授权IFTTT访问他们的Twitter和Gmail帐户。
    
2.  用户保存Applet后，IFTTT将应用程序定义存储在其数据库中。在这个过程中，IFTTT使用AWS RDS来存储**应用程序定义**，并使用AWS Data Pipeline将数据从RDS导出到AWS Redshift中，以供后续**分析和处理**。
    
3.  用户的Twitter账户是作为**触发器**来监视消息的。当IFTTT检测到Twitter帐户收到了一条新的消息时，它将消息推送到Kafka，Kafka是IFTTT数据传输层中的一部分。在这个过程中，IFTTT使用Kafka来实现数据生产者和消费者之间的解耦，以及添加新的数据消费者的松散耦合性。
    
4.  一旦消息推送到**Kafka**，Recipe Worker会从Kafka中读取数据并将它们分配给相应的Applet执行。在这个过程中，IFTTT使用Recipe Worker来执行与应用程序相关的逻辑，例如连接Twitter和Gmail，以及将Twitter消息发送到Gmail。
    
5.  在执行过程中，IFTTT还将使用**Chartio**来监视和分析系统的性能和运行状况。此外，IFTTT还将使用内部监控和告警系统，例如AWS CloudWatch和PagerDuty，来监视系统的状态并通知运营人员进行干预。
    
6.  最后，IFTTT将使用Elasticsearch将处理后的消息存储到集群中，以供后续查询和分析。
    

以上是一个大致的流程，不同的场景可能有些许的不同，但是整体的架构和流程是相似的。**（Drippie同理）**

### trigger(this)数据的获取

1.  在第三方支持**Webhook**情况时，例如Twitter：一旦用户创建了Applet，IFTTT会向Twitter API注册一个webhook，以便Twitter在有新消息时能够将消息发送到IFTTT。IFTTT会**持续监听**Twitter API的推送，一旦有新消息，IFTTT就会将其封装成一个事件，并触发相应的Applet执行。
    
2.  如果第三方不支持 Webhook，IFTTT 可能会使用**轮询**的方式来获取数据并触发 Applet。IFTTT 会使用后台服务，如 Recipe Worker，**定期执行定时器任务**。当定时器任务触发时，IFTTT 会向第三方服务发送 API 请求，以获取最新的数据。如果数据符合 Applet 的触发条件，IFTTT 将触发相应的操作。
    

需要注意的是，轮询方式比 Webhook 方式要**消耗**更多的资源和时间，因为每次轮询都需要向第三方服务发送 API 请求，这可能会导致 API 请求的频率过高，从而影响性能。因此，IFTTT 一般会优先选择支持 Webhook 的第三方服务。

那对于IFTTT每天会有**大量**的Applet去监听执行，所以当有大量的任务需要定时轮询时，每个任务都单独使用一个定时器是不可行的，因为系统资源会被过度占用，导致性能下降。因此，IFTTT 使用了一种基于**时间轮**的调度算法来处理大规模的定时轮询任务。时间轮是一种定时轮询的**数据结构**，可以将定时器按照过期时间分组，并在每个时间间隔内执行一组定时器。因此，IFTTT将所有需要定时轮询的任务按照一定的**规则分组**，然后根据任务的**过期时间**将它们添加到**相应的时间轮**上。这样，当时间轮到达特定的时间间隔时，IFTTT 就可以一次性地执行整个时间轮中的所有任务，而不是一个个单独执行。这样，IFTTT 可以轻松地管理大量的Applet，而不会过度占用系统资源。

Drippie
-------

### 介绍

[Drippie](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-periphery/contracts/universal/drippie/Drippie.sol?ref=dev.optimism.io)是 Optimism 的机制，用于（主要）解决自动化链上活动带来的问题。[Drippie 基本上是If This Then That (IFTTT)](https://ifttt.com/?ref=dev.optimism.io)的以太坊原生版本。与 IFTTT 一样，[Drippie 可以（在 Solidity 中）进行编程](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-periphery/config/drippie/ethereum.ts?ref=dev.optimism.io)以对各种链上数据做出反应，并针对该数据执行各种不同的操作。Drippie 系统中的每组检查/操作都称为“**drip**”。简而言之，它看起来像这样：

![Drippie 操作流程图](https://storage.googleapis.com/papyrus_images/6cd59377aefe606ff79b38f195ccac64c4d0bc3b037a629f16e5291a13e4cc43.png)

Drippie 操作流程图

**什么使Drippie来自动化执行？**

Drippie 是一个允许在特定条件下执行操作的系统。但是，仍然需要一些**服务**来在满足必要条件时**触发**这些操作。

Drippie集成了[Gelato](https://www.gelato.network/?ref=dev.optimism.io)、[Chainlink Keepers](https://chain.link/keepers?ref=dev.optimism.io)或[OpenZeppelin Defender AutoTasks](https://www.openzeppelin.com/defender?ref=dev.optimism.io)等服务，可以定时调用指定drip。

![](https://storage.googleapis.com/papyrus_images/80e4e2e9472bed74dfa14709d9b5e12700985926deca31641ba34355a206c43c.png)

**Gelato**是一个基于以太坊的去中心化**自动化服务**，它可以让智能合约开发者轻松设置条件触发器，例如当以太币价格下降到一定程度时自动执行卖出操作，以实现自动化交易。Gelato 还提供了一些内置条件触发器，例如定时器、价格预警等，以满足各种自动化交易的需求。

**Chainlink Keepers**是**Chainlink**的智能合约**自动化服务**，它可以执行链外任务并触发智能合约。这使得链上智能合约可以响应链外事件，从而可以实现更复杂的智能合约自动化任务。

**OpenZeppelin Defender AutoTasks**是OpenZeppelin的智能合约自动化服务，它可以通过与 Etherscan 和其他链上服务的集成来管理和监视智能合约。AutoTasks提供了一系列内置任务类型和条件触发器，例如执行函数调用、检查合约状态、触发警报等，以实现更可靠的智能合约自动化任务。

**架构图**

![](https://storage.googleapis.com/papyrus_images/cb1bd6d0207b02662a7b9488afe2f95572019a25024f5ee1bf87bc14dbd63008.png)

*   **检查事件**的合约（判断是否到达可执行的状态）
    
*   **执行事件**合约（当检查事件判断到达可执行的状态后，调用该执行合约执行相对应的操作）
    
*   **配置文件** （\*.ts 文件）（包括每次执行drip间隔时间，触发事件，检查事件的合约(check.sol)，执行事件合约(target.sol)等）
    
*   获取每个drip的配置，**调用**Drippie.sol合约中**创建**相对应的drip （\*.ts）
    
*   **Drippie.sol** （生成drip，更新drip状态，查看drip是否到了执行的间隔时间以及drip的状态是否可执行等，官方已部署）
    
*   **定时触发**检查执行的应用（Gelato、keepers、AutoTasks、etc.）
    

### 整体流程：

1.  以 **this为查询账户余额，如果低于某个值** 和 **that为向该账户中转入某个值的金额** 进行举例
    
2.  首先编写并部署 **check.sol**和**target.sol**，check.sol负责对传入的账户检查余额，比如如果余额低于了某个值返回True。target.sol负责去向指定目标账户转账。（check.sol和target.sol都需要根据自己的需求去定）
    
3.  之后填写配置文件中的相对应的参数（可以添加多个drip的配置）： 每两次执行检查的**间隔时间**、**检查**是否达到可执行条件的**合约**(check.sol)、传入该合约function中用到的相对应的参数（比如要检查余额的账户等）、**执行**事件**合约**（target.sol）等等参数
    
4.  通过 [**Install-drippie-config-multisig.ts**](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-periphery/tasks/install-drippie-config-multisig.ts) 文件读取上方配置文件中的每个drip的配置，然后**调用drippie.sol**的**create** function创建相对应的drip，此时合约会判断是否存在该drip、记录该drip相对应地状态以用于在执行时判断是否可执行、创建drip等操作，然后会把这些信息创建一个bundle文件。最后再提交给**Gelato**以供定时调用合约执行。
    
5.  执行drip：Gelato会根据配置去定时调用drippie.sol中的drip function以执行刚刚创建的drip，执行期间首先会调用executable function去检查是否达到了可执行的状态（检查drip相对应地状态）、判断与上次执行的间隔日期是否达到了设置的要求、判断是否达到了可执行条件(check.sol去检查账户的余额是否低于了设定的值)等等验证，如果最后check.sol验证也没问题，执行去调用target.sol执行转账等操作。
    

对比总结
----

从**适用场景**来看：IFTTT主要应用于互联网常用服务的集成，例如邮件、社交网络、智能家居等。适用于普通用户和企业用户。而Drippie面向Web3生态，适用于去中心化的应用和智能合约，主要应用于以太坊智能合约中的定时任务。

**从大体上对模块进行分析**

![](https://storage.googleapis.com/papyrus_images/460afad6eb5a3a55833d34265498917f813391085b459b86e8590ae56bf448e6.png)

IFTTT主要使用API和**Webhooks**技术实现服务的集成和触发，同时也支持自定义应用。

Drippie主要使用**以太坊智能合约**和**Gelato**来实现定时任务的自动化。

而从**灵活性**的角度出发：IFTTT提供的触发器和动作是固定的，不能自定义，用户只能选择现有的触发器和动作进行组合。因此，IFTTT的可编程性相对较低。Drippie则通过智能合约实现交易策略的编程和自动化执行，用户可以自定义各种条件和动作，具有更高的可编程性。

从整体的**完善角度**来看：由于IFTTT已经发展了很长时间，对于用户的使用体验上做得更完善，使用起来也比较简单，集成的服务也比较多，对于存在的Applets有一个很好的监控方案和错误处理机制。而Drippie由于比较新，在这方面还不如IFTTT。

总的来说，IFTTT和Drippie都是自动化任务的工具，但面向的应用场景和技术架构有所不同。IFTTT主要应用于传统互联网领域，通过API和Webhooks将用户不同应用的操作联系起来；Drippie则面向Web3领域，利用智能合约实现自动化交易策略，具有更高的可编程性和安全性，但需要一定的技术门槛。

---

*Originally published on [Yooma](https://paragraph.com/@yooma/web2-ifttt-web3-drippie)*
