外部システムとの連携
OpenAI などの API を呼ぶ、外部サービスの通知を受け取る、外部データベースに接続するなど、用途に応じて連携方法を選べます。
| やりたいこと | 必要な対応 |
|---|---|
| 外部の API を呼ぶ | 接続情報や API キーを設定する |
| アプリの利用者にメールを送る | Email SDK で送る |
| 外部サービスから通知を受ける | Webhook 用のアプリトークンと受信先を設定する |
| 社内の別システムからアプリの API を呼ぶ | アプリトークンと呼び出せるパスを設定する |
| 外部 DB やストレージを使う | 接続情報を設定する |
外部の API を呼ぶ
Section titled “外部の API を呼ぶ”アプリから外部サービスへの通信に制限はありません。例外は SMTP のポート(TCP 25・465・587・2525)で、これらは常に遮断されます。必要な API キーをシークレットに設定し、アプリから呼び出します。外部サービス側の契約や呼び出し回数の制限は、そのサービスの条件に従います。
メールを送信するには、Keelson の Email SDK か、Resend・SendGrid・Mailgun など契約したメール送信サービスの HTTPS API を使います。契約したサービスでも SMTP 中継ホストは使えないため、SMTP のホストとポートではなく API クライアントを設定してください。
一方、外部のシステムからアプリを呼ぶ場合は、既定で Keelson のログインが必要です。ブラウザでログインできないシステムから呼び出すには、以下の設定を行います。
Webhook を受ける
Section titled “Webhook を受ける”Webhook は、外部サービスで起きた出来事をアプリに通知する仕組みです。たとえば決済完了の通知を受けて、注文の状態を更新できます。
Webhook の受信には、webhook スコープのアプリトークンが必要です。送信元の署名がある場合も、このトークンを併用します。auth.endpoints を設定するだけでは、署名のみのリクエストを受け取れるようにはなりません。
まず、対象アプリのトークンを発行します。my-app はアプリの slug に置き換えてください。
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 を呼ぶ場合は、アプリトークンを発行します。
keelson apps tokens create --app my-app --name batch-client --scope api --allowed-ip 203.0.113.0/24my-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 で宣言したパスを呼びます。
curl -H "Authorization: Bearer keelson_xxx" https://acme--my-app.keelson.run/api/external/statusauth: 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 スコープのトークンでは呼び出せません。
メールを送る
Section titled “メールを送る”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 回までです
- 月ごとに送れる宛先数は、プランごとに決まっています(プランと制限)。当月の使用量は、コンソールのワークスペース設定の「メール」で確認できます
自社のドメインから送る
Section titled “自社のドメインから送る”Team プランでは、ワークスペースが所有するドメインのアドレス(例 [email protected])を差出人にして送れます。ドメインはワークスペースあたり 10 件まで、差出人に使える許可アドレスはドメインあたり 20 件まで登録できます。設定は Owner / Admin が、コンソールのワークスペース設定の「メール」>「送信ドメイン」で行います。ドメインの DNS 設定を変更できる権限が必要です。
- 「ドメインを追加」でドメインを入力します。1 つのアプリだけに使わせる場合は「スコープ」でアプリを選びます。選ばなければ、ワークスペースのすべてのアプリが使えます。
- 「所有の確認」に表示された TXT レコードを DNS に追加し、「状態を確認」を押します。1 つのドメインを所有確認できるのは 1 ワークスペースだけです。
- 所有が確認されると、メールの署名(DKIM)用の CNAME レコードが 3 件表示されます。DNS に追加してください。検証は通常数分で終わります。状態は「状態を確認」を押すと確認できます。72 時間以内にレコードが見つからない場合は検証に失敗します。ドメインを削除して追加し直してください。
- 「許可アドレス」に、アプリが差出人に使うアドレスを追加します。
- アプリでは、そのアドレスを
from_address(Node・Python)またはFrom(Go)に渡します。
await email.send({ from_name: "Example サポート", subject: "申請を受け付けました", text: "申請番号 1234 を受け付けました。",});- 差出人は送信のたびに確認されます。送信するアプリのワークスペースで検証済みのドメインの許可アドレスと完全に一致しない差出人(大文字・小文字は区別しません)は、送信を拒否します。許可アドレスを削除すると、次の送信から拒否されます
- メールには自社のドメインの DKIM 署名が付き、DMARC の判定で差出人のドメインと整合します。返送先(SPF)には自社のドメインを使わないため、SPF は整合しません
- 既定の差出人
<アプリの slug>@mail.keelson.runは、許可アドレスの登録なしでそのまま使えます - ワークスペースが Team プランでなくなると、自社のドメインからの送信は拒否されます。登録したドメインと許可アドレスは残り、Team に戻すと再び使えます
- バウンス・苦情と抑止リストは、既定の差出人と同じように働きます
送れなかったとき
Section titled “送れなかったとき”送信できない場合、SDK はエラーを送出します。エラーメッセージにエラーコードが含まれます。
| HTTP | エラーコード | 意味 |
|---|---|---|
| 400 | RECIPIENT_SUPPRESSED | 宛先が、ワークスペースの抑止リストに載っています(下記) |
| 403 | EMAIL_SENDING_SUSPENDED | ワークスペースのメール送信が停止されています。恒久的なバウンスや苦情が多いと、ワークスペース全体の送信が自動で停止します。解除はお問い合わせください |
| 403 | SENDER_DOMAIN_NOT_AVAILABLE | 差出人が自社のドメインですが、ワークスペースが Team プランではありません |
| 403 | DOMAIN_NOT_VERIFIED | 差出人のドメインが、送信するアプリのワークスペースで検証済みでないか、別のアプリに限定されています |
| 403 | SENDER_ADDRESS_NOT_ALLOWED | 差出人が、そのドメインの許可アドレスに登録されていません |
| 422 | RECIPIENT_LIMIT_EXCEEDED | 宛先が合計 50 件を超えています |
| 429 | RATE_LIMIT_EXCEEDED | 60 秒あたりの送信回数の上限に達しました。時間をおいて送り直します |
| 429 | MONTHLY_QUOTA_EXCEEDED | 当月の宛先数の上限に達しました。翌月にリセットされます |
| 429 | GLOBAL_RATE_LIMIT_EXCEEDED / GLOBAL_DAILY_QUOTA_EXCEEDED | Keelson 全体の送信量が一時的に上限に達しました。時間をおいて送り直します |
| 502 | SEND_OUTCOME_UNKNOWN | 送信されたかを確認できませんでした。届いている可能性があるため、自動では送り直さないでください |
メールの配信結果を受け取る
Section titled “メールの配信結果を受け取る”送ったメールが届いたか、宛先が存在しないなどの理由で返ってきたか(バウンス)、受信者が迷惑メールとして報告したか(苦情)を、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_type | delivered(届いた)・bounce(バウンス)・complaint(苦情) |
email_address | 対象の宛先 |
send_id | 送信時に返された send_id。送信の記録との突き合わせに使います |
bounce_type | バウンスのとき、hard(恒久的)か soft(一時的) |
detail | 補足の情報 |
provider | 配信に使った送信基盤の名前 |
timestamp | 発生時刻 |
受信処理が 2xx を返すと通知は完了します。5xx を返したときやアプリに届かなかったときは、時間をおいて合計 4 回まで試みます。4xx を返した通知は送り直しません。
外部データベース
Section titled “外部データベース”PostgreSQL、MySQL、自前の libSQL に接続する場合は db.mode: none にし、接続情報をシークレットで渡します。詳しくはデータベースを参照してください。
外部オブジェクトストレージ
Section titled “外部オブジェクトストレージ”Files / Media SDK の上限を超えるファイルは、S3 互換のストレージにアプリから直接保存します。認証情報はシークレットで渡します。