💬 チャット
チャットは、chatService を通じてチャンネル、メッセージ、添付ファイル、テンプレート、サブスクリプション、およびチャンネルごとの既読状態のための HTTP および WebSocket 合成機能を提供します。
ここから始めましょう
サービスを /api 以下にマウントします。defService は返されたルーターに JSON パースをインストールします。Cookie 認証ではさらにマウント前に cookie-parser が必要です。署名付き添付ファイルとチャンネルアイコンの操作には fileStorageDriver が必要で、現在のサービスは常に WebSocket ルートを合成するため webSocketServer を受け取る必要があります。
chatService は authMode === 'cookie' の場合 getCookieTokenInfo を選択し、デフォルトでは getBearerTokenInfo を選択します。型付きストアには identities、chatChannels、subscriptions、chatMessages、および chatChannelReadStates が必要です。organizations と chatMessageTemplates は型のオプションですが、それらをクエリするルートでは実行時に必須です。
import express from 'express';
import cookieParser from 'cookie-parser';
import { services } from '@nodeblocks/backend-sdk';
const app = express();
app.use(cookieParser()); // authMode: 'cookie' のみ必要。
app.use('/api', services.chatService(
{ identities, chatChannels, organizations, subscriptions, chatMessages, chatMessageTemplates, chatChannelReadStates },
{
authSecrets: { authEncSecret: process.env.AUTH_ENC_SECRET!, authSignSecret: process.env.AUTH_SIGN_SECRET! },
authMode: 'bearer',
identity: { typeIds: { admin: 'admin-type-id', guest: 'guest-type-id', regular: 'regular-type-id' } },
organization: { roles: { admin: 'organization-admin-role-id', member: 'organization-member-role-id', owner: 'organization-owner-role-id' } },
},
{ fileStorageDriver, webSocketServer },
));
| 設定 | デフォルト / ソースの動作 | 効果 |
|---|---|---|
authSecrets.authEncSecret | 必須; 合成されたすべての機能に configuration を通じて渡される | 必須の認証秘密材料。 |
authSecrets.authSignSecret | 必須; 合成されたすべての機能に configuration を通じて渡される | 必須の認証秘密材料。 |
authMode | 省略と 'bearer' は getBearerTokenInfo を選択; 'cookie' は getCookieTokenInfo を選択 | 保護されたルートのアクセストークン転送を選択します。 |
identity.typeIds.admin | 管理者チェックで読み取られます | チャンネル、サブスクリプション、およびテンプレートのアクセスルールの管理者ブランチを有効にします。 |
organization.roles.owner / admin | テンプレートルートで読み取られます | オrganization-テンプレート認証を有効にします。 |
fileStorageDriver | 添付ファイルのアップロード/ダウンロード URL およびチャンネルアイコンのアップロード URL に必須 | 署名済みファイル操作を提供します。 |
webSocketServer | 現在の完全な chatService を構築する際に必須 | streamChatMessagesRoute を登録します。 |
よくあるタスク
| タスク | 開始点 | 契約 |
|---|---|---|
| チャンネルの管理 | チャンネル機能 | 機能、ルート |
| メッセージの送信、一覧表示、編集、ストリーミング | メッセージ機能 | ルート、スキーマ |
| ファイルの添付またはアップロード URL の取得 | ファイルストレージ搭載ルート | ブロック、ルート |
| テンプレート、サブスクリプション、および既読状態の管理 | テンプレート機能グループ | 機能 |
チャットは公開 HTTP エンドポイントを公開しません。すべての HTTP ルートは isAuthenticated() から始まります。WebSocket ストリームは現在未保護です。意図されていた認証とサブスクリプション検証子がコメントアウトされているため、これは公開 HTTP 認証ワークフローではなくソースの制限です。
Bearer HTTP ワークフロー
export ACCESS_TOKEN='replace-with-an-access-token'
export CHANNEL_ID='replace-with-a-channel-id'
curl -X POST 'http://localhost:8080/api/channels' \
-H "authorization: Bearer $ACCESS_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"Support","description":"Customer support"}'
curl "http://localhost:8080/api/channels/$CHANNEL_ID/messages" \
-H "authorization: Bearer $ACCESS_TOKEN"
これはホストアプリケーションの断片です。トークンは既存のアイデンティティを識別する必要があり、2 番目のリクエストでは既存のチャンネルサブスクリプションが必要です。チャンネルの作成は 201 とともに正規化されたチャンネルを data に返します。チャンネルメッセージの検索は正規化されたメッセージとページネーションメタデータとともに 200 を返します。不足または無効なトークンは認証に失敗し、不足したサブスクリプションは認可に失敗します。createChatChannelRoute、createChatChannelSchema、getChannelMessagesRoute、および getChannelMessagesSchema を参照してください。
Cookie HTTP ワークフロー
authMode: 'cookie' では、チャットの前に cookie-parser を登録し、認証 を通じてアクセスクッキーを取得し、そのクッキーをリクエストに含めます。この例は、トークンアイデンティティが要求されたスコープと一致する場合、正規化されたチャンネルとページネーションメタデータとともに 200 を返します。不足または無効なクッキーは認証に失敗します。同じ保護ルートルールが適用されます - トークンの抽出のみが変更されます。findChatChannelsRoute および findChatChannelsSchema を参照してください。
export ACCESS_COOKIE='accessToken=replace-with-an-access-token'
curl 'http://localhost:8080/api/channels' \
-H "cookie: $ACCESS_COOKIE"
WebSocket ワークフロー
構築前に chatService に webSocketServer を渡してから、必要な channelId クエリ値が streamChatMessagesSchema で定義された streamChatMessagesRoute に接続します。ルートは /messages/listen でプロトコル ws を使用し、正規化された挿入メッセージを JSON として送出します。不足したチャンネル ID は 400 に、ストリーム構築の失敗は 500 にマッピングされます。意図されていた isAuthenticated() および hasSubscription(...) 検証子は現在ソースでコメントアウトされているため、構成された Bearer/cookie 抽出はこのエンドポイントでは強制されません。
カスタム機能合成
ホストに必要な公開機能出力のみを合成し、chatService が渡すのと同じデータストア/設定コンテキストで defService を呼び出します。選択された機能が必要とする場合のみ fileStorageDriver と webSocketServer を追加します。
import { partial } from 'ramda';
import { features, primitives, utils } from '@nodeblocks/backend-sdk';
const channelFeature = primitives.compose(
features.createChannelFeature,
features.getChannelFeature,
);
const router = primitives.defService(partial(channelFeature, [{
authenticate: utils.getBearerTokenInfo,
configuration,
dataStores: { identities, chatChannels, subscriptions },
fileStorageDriver,
}]));
app.use('/api', router);
この HTTP のみのカスタム合成は streamChatMessagesFeature を含まないため、WebSocket サーバーを必要としません。選択された機能によって読み取られるすべてのコレクションとドライバーを提供します。
リファレンスマップ
| ページ | 目的 |
|---|---|
| ブロック | 再利用可能な永続化、正規化、署名済みファイル、およびストリーム操作。 |
| 機能 | スキーマからルートへの合成。 |
| ハンドラー | HTTP パイプライン操作とターミネーター。 |
| ルート | 正確な HTTP および WebSocket エンドポイント契約。 |
| スキーマ | フィールドレベルの要求契約。 |
| 検証子 | 共有アクセスおよび存在ガード。 |
関連モジュール
トークン転送については 認証、署名済みファイルドライバーについては file-storage、役割構成については Organization、共有失敗については エラー処理 を参照してください。