asopi tech
asopi techIndie Developer

Asopitech With · 自動化サービス

IFTTT with Alopex DB

IFTTTは、アプリや機器をトリガーとアクションでつなぐ自動化サービスです。これをAlopex DBを使って再現すると…?

更新: 2026/10/12

どんなサービスか

IFTTTのような自動化サービスは、アプリ、機器、サービスをつなぎます。利用者は、トリガーとアクションを組み合わせたアプレットを作ります。毎朝の天気予報を受け取る、家を出たら防犯をオンにする、といった自動化です。扱うデータは、利用者、つないだサービス、アプレットの定義、トリガーのイベント、実行の記録です。

データの置き場所

  • SQLテーブル:利用者、つないだサービス、アプレットをテーブルに持ちます。トリガーとアクションの設定は、サービスごとに形が違うので、JSONの列に入れます。
  • トランザクション:届いたトリガーのイベントは、イベントの識別子に一意の制約を付けたテーブルに入れます。イベントの記録と、実行の予約を、同じトランザクションでコミットします。同じイベントが何度届いても、アプレットの実行は重なりません。
  • カラムナーテーブル:実行の記録を、HTTPの取り込みでカラムナーテーブルにまとめて入れます。アプレットごとの成功の割合や、サービスごとの失敗の傾向をSQLで集計します。

サービスを定期的に確かめるスケジューラーと、アクションを呼び出すワーカーは、アプリのコードです。どちらもAlopex DBに読み書きして、状態を共有します。

配置の形

Alopex DBをサーバーとして立てます。トリガーを受ける窓口、スケジューラー、ワーカーが、それぞれHTTPかgRPCで同じデータベースにつなぎます。運用の担当者は、CLIから同じデータベースにSQLを打って調べます。利用が広がったら、同じSQLのままAlopex DBのクラスタに広げます。

Alopex DBが合う理由

自動化サービスでは、設定、イベント、記録という性格の違うデータが、たくさんのプロセスから同時に読み書きされます。Alopex DBは、テーブルとJSON、カラムナーの記録を、HTTP、gRPC、CLIのどこからでも同じSQLで扱い、トランザクションで重複を防ぎます。

コードで見る

届いたトリガーのイベントを一意の制約で受け、実行の予約と同じトランザクションでコミットします。二重実行を防ぐ中心だけを取り出したコードです。

import alopex

db = alopex.Database.open("ifttt.alopex")

db.execute_sql("CREATE TABLE IF NOT EXISTS applets (id INTEGER PRIMARY KEY, name TEXT)")
db.execute_sql("CREATE TABLE IF NOT EXISTS trigger_events (event_id TEXT UNIQUE, applet_id INTEGER)")
db.execute_sql("CREATE TABLE IF NOT EXISTS executions (applet_id INTEGER, state TEXT)")
db.execute_sql("INSERT INTO applets (id, name) VALUES (?, ?)", [1, "雨なら傘を通知"])

# 届いたトリガーを記録し、新しいときだけ実行を予約する(同じイベントで二重実行しない)
def on_trigger(event_id, applet_id):
    tx = db.begin(alopex.TxnMode.READ_WRITE)
    try:
        n = tx.execute_sql(
            "INSERT INTO trigger_events (event_id, applet_id) VALUES (?, ?) ON CONFLICT (event_id) DO NOTHING",
            [event_id, applet_id],
        )
        if n:  # 新しいイベントのときだけ実行を予約する
            tx.execute_sql("INSERT INTO executions (applet_id, state) VALUES (?, ?)", [applet_id, "queued"])
        tx.commit()
    except Exception:
        tx.rollback()
        raise

on_trigger("evt-001", 1)
on_trigger("evt-001", 1)  # 同じイベントが再送されても…
on_trigger("evt-002", 1)

# 予約された実行の数(二重実行していないことを確かめる)
print("実行予約:", db.execute_sql("SELECT COUNT(*) AS n FROM executions")[0]["n"])

同じイベントが何度届いても、一意の制約とトランザクションで、実行はちょうど一度にそろいます。

ルールをSQLとJSONで持ち、実行の記録をカラムナーテーブルにためられるAlopex DBのサーバーは、自動化のサービスにおすすめです。クイックスタートもあわせてどうぞ。

関連リンク