コンテンツにスキップ
コンソール →
公式サイト →
URL を貼り付けて AI に質問 https://keelson.dev/ja/llms.txt

外部システムとの連携

OpenAI などの API を呼ぶ、外部サービスの通知を受け取る、外部データベースに接続するなど、用途に応じて連携方法を選べます。

やりたいこと必要な対応
外部の API を呼ぶ接続情報や API キーを設定する
アプリの利用者にメールを送るEmail SDK で送る
外部サービスから通知を受けるWebhook 用のアプリトークンと受信先を設定する
社内の別システムからアプリの API を呼ぶアプリトークンと呼び出せるパスを設定する
外部 DB やストレージを使う接続情報を設定する

アプリから外部サービスへの通信に制限はありません。例外は SMTP のポート(TCP 25・465・587・2525)で、これらは常に遮断されます。必要な API キーをシークレットに設定し、アプリから呼び出します。外部サービス側の契約や呼び出し回数の制限は、そのサービスの条件に従います。

メールを送信するには、Keelson の Email SDK か、Resend・SendGrid・Mailgun など契約したメール送信サービスの HTTPS API を使います。契約したサービスでも SMTP 中継ホストは使えないため、SMTP のホストとポートではなく API クライアントを設定してください。

一方、外部のシステムからアプリを呼ぶ場合は、既定で Keelson のログインが必要です。ブラウザでログインできないシステムから呼び出すには、以下の設定を行います。

Webhook は、外部サービスで起きた出来事をアプリに通知する仕組みです。たとえば決済完了の通知を受けて、注文の状態を更新できます。

Webhook の受信には、webhook スコープのアプリトークンが必要です。送信元の署名がある場合も、このトークンを併用します。auth.endpoints を設定するだけでは、署名のみのリクエストを受け取れるようにはなりません。

まず、対象アプリのトークンを発行します。my-app はアプリの slug に置き換えてください。

Terminal window
keelson apps tokens create --app my-app --name webhook-client --scope webhook

アプリに POST /api/webhooks/incoming などの受信処理を実装します。次のパスをアプリの URL(例:https://acme--my-app.keelson.run)に付け、送信元の受信先として登録します。

送信元で設定できるもの設定方法
任意の HTTP ヘッダー受信 URL を /api/webhooks/incoming にし、X-Webhook-Secret: <発行したトークン> を付ける
受信 URL のみ受信 URL を /api/webhooks/<発行したトークン>/incoming にする

URL にトークンを含めた場合、Keelson はトークン部分を取り除き、アプリの /api/webhooks/incoming に渡します。トークンを含む URL は秘密の値として扱ってください。これらのリクエストにログインユーザーの情報は付きません。

Keelson はトークンの有効性、対象アプリ、webhook スコープ、送信元 IP の制限を確認します。現在、Webhook のパスやメソッドを auth.endpoints で制限することはできません。受信処理で許可するパスとメソッドを確認してください。

送信元が署名を付ける場合は、署名シークレットを secrets で受け取り、アプリ側でも署名を検証します。Keelson のアプリトークンは、送信元の署名シークレットとは別のものです。

なお /api/webhooks/email と /api/webhooks/email-events はプラットフォーム予約のため、独自の Webhook の受信先には使えません。auth.endpoints には追加しないでください。

別のシステムからアプリの API を呼ぶ

Section titled “別のシステムからアプリの API を呼ぶ”

社内の別システムやスクリプトからアプリの API を呼ぶ場合は、アプリトークンを発行します。

Terminal window
keelson apps tokens create --app my-app --name batch-client --scope api --allowed-ip 203.0.113.0/24

my-app は対象アプリの slug、203.0.113.0/24 は実際の送信元 IP の範囲に置き換えます。

  • トークンは keelson_... の形式で、作成時に 1 回だけ表示されます
  • --scope api は /api/external/ 配下、--scope webhook は /api/webhooks/ 配下に対応します
  • --allowed-ip で送信元 IP を絞れます(CIDR、複数可)。ワークスペースやアプリの IP 制御とは別に、トークン単位で適用されます
  • 同じ設定はコンソールのアプリ画面からも行えます。CLI の keelson apps tokens 配下には、一覧を表示する list、トークンを更新する rotate、失効させる delete があります

呼び出し側は Authorization: Bearer keelson_... を付けて、auth.endpoints で宣言したパスを呼びます。

Terminal window
curl -H "Authorization: Bearer keelson_xxx" https://acme--my-app.keelson.run/api/external/status
auth:
endpoints:
- path: /api/external/status
methods: [GET]
- /api/external/import # メソッド指定なし = すべて

Keelson は、トークンが有効で対象アプリ・用途に合っていること、送信元 IP が許可されていること、パスとメソッドが宣言に合っていることを確認してから、アプリにリクエストを渡します。

auth.endpoints のパスは完全一致ではなく、先頭の文字列で照合されます。たとえば /api/external/status は /api/external/status/detail や /api/external/status-old にも一致します。アプリ側でも受け付けるパスとメソッドを確認してください。宣言していない API は、api スコープのトークンでは呼び出せません。

Keelson の Email SDK を使うと、メール送信サービスを契約せずに、アプリからアプリの利用者へメールを送れます。パスワード再設定、申請の受付通知、承認依頼などの業務連絡に使います。

送信できるのは、そのアプリの利用者への業務上の連絡だけです(利用ポリシー 2.3)。マーケティングの一斉送信、購入した宛先リストへの送信、アプリを使っていない人への送信はできません。継続的に送る通知には、受信者が受信を停止できる手段を設けてください。

import * as email from "@keelsonhq/email";
const result = await email.send({
subject: "申請を受け付けました",
text: "申請番号 1234 を受け付けました。",
});
// result.send_id を保存しておくと、配信結果と突き合わせられます

Python では from keelson import email で読み込み、email.send(...) を呼びます。Go では github.com/keelsonhq/go-sdk/email の email.New("", "") でクライアントを作り、Send を呼びます。インストールは Keelson SDK を参照してください。

  • 接続先とトークン(KEELSON_EMAIL_TOKEN など)は、Keelson がデプロイ時に自動で設定し、SDK が読み取ります。keelson.yaml への追加設定は不要です。静的サイト・SPA には SDK を動かすサーバーがないため送れません
  • 差出人は、既定では <アプリの slug>@mail.keelson.run です。表示名(from_name)と返信先(reply_to)は指定できます。Team プランでは、自社のドメインの許可したアドレスも差出人にできます(下記)
  • 1 通の宛先は To・CC・BCC の合計で 50 件までです。本文には text か html の少なくとも一方が必要です
  • 送信の回数は、アプリごと・ワークスペースごとにそれぞれ 60 秒あたり 30 回までです
  • 月ごとに送れる宛先数は、プランごとに決まっています(プランと制限)。当月の使用量は、コンソールのワークスペース設定の「メール」で確認できます

Team プランでは、ワークスペースが所有するドメインのアドレス(例 [email protected])を差出人にして送れます。ドメインはワークスペースあたり 10 件まで、差出人に使える許可アドレスはドメインあたり 20 件まで登録できます。設定は Owner / Admin が、コンソールのワークスペース設定の「メール」>「送信ドメイン」で行います。ドメインの DNS 設定を変更できる権限が必要です。

  1. 「ドメインを追加」でドメインを入力します。1 つのアプリだけに使わせる場合は「スコープ」でアプリを選びます。選ばなければ、ワークスペースのすべてのアプリが使えます。
  2. 「所有の確認」に表示された TXT レコードを DNS に追加し、「状態を確認」を押します。1 つのドメインを所有確認できるのは 1 ワークスペースだけです。
  3. 所有が確認されると、メールの署名(DKIM)用の CNAME レコードが 3 件表示されます。DNS に追加してください。検証は通常数分で終わります。状態は「状態を確認」を押すと確認できます。72 時間以内にレコードが見つからない場合は検証に失敗します。ドメインを削除して追加し直してください。
  4. 「許可アドレス」に、アプリが差出人に使うアドレスを追加します。
  5. アプリでは、そのアドレスを from_address(Node・Python)または From(Go)に渡します。
await email.send({
from_address: "[email protected]",
from_name: "Example サポート",
subject: "申請を受け付けました",
text: "申請番号 1234 を受け付けました。",
});
  • 差出人は送信のたびに確認されます。送信するアプリのワークスペースで検証済みのドメインの許可アドレスと完全に一致しない差出人(大文字・小文字は区別しません)は、送信を拒否します。許可アドレスを削除すると、次の送信から拒否されます
  • メールには自社のドメインの DKIM 署名が付き、DMARC の判定で差出人のドメインと整合します。返送先(SPF)には自社のドメインを使わないため、SPF は整合しません
  • 既定の差出人 <アプリの slug>@mail.keelson.run は、許可アドレスの登録なしでそのまま使えます
  • ワークスペースが Team プランでなくなると、自社のドメインからの送信は拒否されます。登録したドメインと許可アドレスは残り、Team に戻すと再び使えます
  • バウンス・苦情と抑止リストは、既定の差出人と同じように働きます

送信できない場合、SDK はエラーを送出します。エラーメッセージにエラーコードが含まれます。

HTTPエラーコード意味
400RECIPIENT_SUPPRESSED宛先が、ワークスペースの抑止リストに載っています(下記)
403EMAIL_SENDING_SUSPENDEDワークスペースのメール送信が停止されています。恒久的なバウンスや苦情が多いと、ワークスペース全体の送信が自動で停止します。解除はお問い合わせください
403SENDER_DOMAIN_NOT_AVAILABLE差出人が自社のドメインですが、ワークスペースが Team プランではありません
403DOMAIN_NOT_VERIFIED差出人のドメインが、送信するアプリのワークスペースで検証済みでないか、別のアプリに限定されています
403SENDER_ADDRESS_NOT_ALLOWED差出人が、そのドメインの許可アドレスに登録されていません
422RECIPIENT_LIMIT_EXCEEDED宛先が合計 50 件を超えています
429RATE_LIMIT_EXCEEDED60 秒あたりの送信回数の上限に達しました。時間をおいて送り直します
429MONTHLY_QUOTA_EXCEEDED当月の宛先数の上限に達しました。翌月にリセットされます
429GLOBAL_RATE_LIMIT_EXCEEDED / GLOBAL_DAILY_QUOTA_EXCEEDEDKeelson 全体の送信量が一時的に上限に達しました。時間をおいて送り直します
502SEND_OUTCOME_UNKNOWN送信されたかを確認できませんでした。届いている可能性があるため、自動では送り直さないでください

送ったメールが届いたか、宛先が存在しないなどの理由で返ってきたか(バウンス)、受信者が迷惑メールとして報告したか(苦情)を、Keelson がアプリの POST /api/webhooks/email-events に通知します。結果を使う場合は、このパスに受信処理を実装します。アプリトークンや auth.endpoints の設定は不要です。

恒久的なバウンスと苦情を受けた宛先は、受信処理の有無にかかわらず、ワークスペースの抑止リストに自動で載ります。以後、同じワークスペースのどのアプリからもその宛先には送れません(RECIPIENT_SUPPRESSED)。抑止リストは、Owner / Admin がコンソールのワークスペース設定の「メール」で確認・削除できます。

通知には署名が付いています。SDK で署名を検証してから内容を使います。署名の鍵 KEELSON_EMAIL_WEBHOOK_SECRET は Keelson が自動で設定します。

import * as email from "@keelsonhq/email";
// POST /api/webhooks/email-events の受信処理。rawBody は受け取った本文そのもの
const event = email.verifyEventWebhookBytes(
rawBody,
req.headers,
process.env.KEELSON_EMAIL_WEBHOOK_SECRET!,
);
if (event.event_type === "bounce" && event.bounce_type === "hard") {
// event.send_id で送信時の記録を探し、宛先を無効にする
}

Python では email.verify_event_webhook(body, headers, secret)、Go では email.VerifyEventWebhook(r, secret) を使います。署名は本文のバイト列に対して検証するため、JSON として解析し直す前の本文を渡してください。

項目内容
event_id通知の ID。同じ通知が重複して届くことがあるため、重複の判定に使います
event_typedelivered(届いた)・bounce(バウンス)・complaint(苦情)
email_address対象の宛先
send_id送信時に返された send_id。送信の記録との突き合わせに使います
bounce_typeバウンスのとき、hard(恒久的)か soft(一時的)
detail補足の情報
provider配信に使った送信基盤の名前
timestamp発生時刻

受信処理が 2xx を返すと通知は完了します。5xx を返したときやアプリに届かなかったときは、時間をおいて合計 4 回まで試みます。4xx を返した通知は送り直しません。

PostgreSQL、MySQL、自前の libSQL に接続する場合は db.mode: none にし、接続情報をシークレットで渡します。詳しくはデータベースを参照してください。

Files / Media SDK の上限を超えるファイルは、S3 互換のストレージにアプリから直接保存します。認証情報はシークレットで渡します。