1767311729
2026-01-01 00:00:00
Optimizely Connect Platform (OCP) アプリを構築する方法
の Optimizely Connect Platform (OCP): Optimizely One エコシステム全体でシステムを接続する そして、Optimizely One 全体のシステムがクリーンかつ一貫してデータを交換できるようにする方法を検討しました。この投稿は、プラットフォームをより実践的で開発者に焦点を当てて考察することで、その基盤に基づいて構築されています。
この記事では、プロジェクトのスキャフォールディングとデータ スキーマの定義から、ジョブの実装、アプリの検証、統合の公開まで、Cloudinary に接続する OCP アプリを作成するプロセスを順を追って説明します。
はじめる
Cloudinary コネクタの構築を開始する前に、いくつかの前提条件を整えておく必要があります。
1. OCP 開発者アカウントを取得する
Optimizely にアクセスをリクエストして、ツールと権限を取得します。を参照してください。 最適化されたドキュメント 詳細については。
2. 開発環境をセットアップする
要件:
設定を確認します。
1ocp --version
3. 新しいアプリのスキャフォールディング
1ocp app init
これにより、以下が作成されます。
-
アプリの定義
-
スキーマYAML
-
ジョブフォルダー
-
機能フォルダー
-
設定フォーム
スキャフォールドされたアプリケーションは優れた出発点であり、この例で使用される Cloudinary コネクタの基盤となります。
アプリケーションの構築
アプリケーションのスキャフォールディングが完了したので、Cloudinary コネクタの構築に進むことができます。
1。アプリケーション設定
アプリケーションが認証して Cloudinary と通信できるように、資格情報と統合エンドポイントを取得する必要があります。 OCP インターフェイスを拡張してこれらをキャプチャし、アプリケーション内で使用できるように安全に保存することができます。
設定.yml
の 'settings.yml' ファイルはフォームを定義するために使用されます。このフォームには、アプリケーションに必要なすべての設定がキャプチャされます。フォームにはセクションを含めることができ、設定を論理的にグループ化できます。
1sections:
2 - key: authorisation
3 label: Authorisation
4 elements:
5 - type: text
6 key: url
7 label: Integration URL
8 help: The URL of the Cloudinary account to integrate with. This is typically in the format `https://api.cloudinary.com/v1_1/>`.
9 hint: https://api.cloudinary.com/v1_1/>
10 required: true
11 - type: text
12 key: username
13 label: Username
14 help: The username for the Cloudinary account.
15 required: true
16 - type: secret
17 key: password
18 label: Passwword
19 help: The password for the Cloudinary account.
20 required: true
21 - type: button
22 label: Save
23 action: save
24 style: primary
25 - type: button
26 label: Start Sync
27 action: sync
28
フォームにはさまざまなフィールド タイプを含めることができます。フィールドには検証を含めることができ、外部データ ソースを参照することもできます。詳細については、Optimizely のドキュメントを参照してください。 さらに読む。
フォームのライフサイクル
上で説明したように、 'settings.yml' ファイルはフォームを定義するために使用されますが、ユーザーが値を入力するときに値を操作するためのメカニズムも必要です。
の 'Lifecycle.ts' ファイルには、このタスクを正確に実行する関数「onSettingsForm」が含まれています。
1 public async onSettingsForm(
2 section: string,
3 _action: string,
4 formData: SubmittedFormData
5 ): PromiseLifecycleSettingsResult> {
6 const result = new LifecycleSettingsResult();
7 try {
8
9 if (section === 'authorisation') {
10
11 switch (_action) {
12 case 'save':
13 await storage.settings.put(section, formData);
14 await registerWebhooks(formData.url as string,
15 formData.username as string,
16 formData.password as string);
17
18 break;
19 }
20 }
21
22 return result;
23
24 } catch {
25 return result.addToast(
26 'danger',
27 'Sorry, an unexpected error occurred. Please try again in a moment.'
28 );
29 }
30 }
上記のコードは、「保存フォーム上の「」ボタンが押されました。コードスニペット内
-
フォーム値は OCP ストレージに保存されます。
-
カスタム関数 ‘Webhook を登録する』と呼ばれる。これにより、OCP Webhook が Cloudinary に登録されます (これについては後で詳しく説明します)。
2。データスキーマ
これは「データ同期アプリ‘ では、Cloudinary から同期している画像データを保存するデータ オブジェクトを定義する必要があります。
データ オブジェクト スキーマは YML として定義されており、 'schema' フォルダ。
1name: cloudinary_image
2display_name: Cloudinary Image
3fields:
4 - name: asset_id
5 type: string
6 display_name: Asset ID
7 description: Unique identifier for the asset in Cloudinary.
8 primary: true
9
10 - name: public_id
11 type: string
12 display_name: Public ID
13 description: Public identifier for the asset, used in URLs and API calls.
14
15 - name: format
16 type: string
17 display_name: Format
18 description: Document format, e.g. jpg, png, etc.
19
20 - name: version
21 type: number
22 display_name: Version
23 description: Document version
24
25 - name: resource_type
26 type: string
27 display_name: Resource Type
28 description: Type of resource, e.g. image, video, etc.
29
30 - name: type
31 type: string
32 display_name: Type
33 description: Type of upload, e.g. upload, private, authenticated, etc.
34
3。求人
Optimizely には「」という概念があります。仕事‘。これらは、初期データ ロードの処理など、長時間実行されるプロセスをサポートするように設計されています。ジョブは (cron 経由で) スケジュールすることも、オンデマンドで実行することもできます。
中心となる概念
ジョブは長時間実行プロセスをサポートしますが、処理がバッチで実行され、各バッチがデータ全体のサブセットを処理するように作成する必要があります。 Cloudinary の例では、すべての画像を一度にロードしません。それらを小さなチャンクに分けてロードします。
準備する
このメソッドは、ジョブが処理するバッチを構成するために呼び出されます。ここで、初期ロードの状態が定義されるか、前の実行の状態が次のバッチ プロセスに渡されます。
実行する
ここで実際の処理が行われます。状態を受け取り、それを使用して次にロードするイメージのセットを決定します。
処理の実行時間は60秒以内に抑える必要があります。親 OCP プロセスはそれ以上終了する可能性があります。
1 public async perform(
2 status: HistoricalImportJobStatus
3 ): PromiseHistoricalImportJobStatus> {
4 const state = status.state;
5 let encounteredError = false;
6 try {
7 // fetch some assets from our API
8 const response = await this.fetch(state.cursor, 500);
9
10 logger.info(`response ${response.status}, ${response.statusText} `);
11
12 if (response.ok) {
13
14 const result = (await response.json()) as HistoricalImportResult;
15 const cursor = result.next_cursor ?? '';
16
17 // Update our state so the next iteration can continue where we left off
18 state.cursor = cursor;
19 state.count += result.resources.length;
20
21 // Transform our assets and send a batch to Optimizely Hub
22 if (result.resources.length > 0) {
23 await odp.object('cloudinary_image', result.resources.map(transformAssetToPayload));
24 }
25
26 // In this example, 0 assets means we have imported all the data
27 if (result.resources.length === 0 || cursor.length === 0) {
28 // Notify the customer we completed the import and provide some information to show it was successful
29 await notifications.success(
30 'Historical Import',
31 'Completed Historical Import',
32 `Imported ${state.count} assets.`
33 );
34 status.complete = true;
35 return status;
36 }
37
38 } else {
39 logger.error(
40 'Historical import error:',
41 response.status,
42 response.body.read().toString()
43 );
44 encounteredError = true;
45 }
46 } catch (e) {
47 // Log all handled errors for future investigation. Customers will not see these logs.
48 logger.error(e);
49 encounteredError = true;
50 }
51
52 // If we encountered an error, backoff and retry up to 5 times
53 if (encounteredError) {
54 if (state.retries >= 5) {
55 // Notify the customer there was a problem with the import
56 await notifications.error(
57 'Historical Import',
58 'Failed to complete historical import',
59 'Maximum retries exceeded'
60 );
61 status.complete = true;
62 } else {
63 state.retries++;
64 await this.sleep(state.retries * 5000);
65 }
66 }
67
68 // Our state has been updated inside status so we know where to resume
69 return status;
70 }
上記のコードでは、Cloudinary から次の 500 枚の画像を取得しています。画像がある場合は、OCP データベースに保存します。それ以外の場合は、すべての画像がロードされたものとみなし、処理を停止します。
GitHub リポジトリでジョブの完全なコードを表示します。 HistoricalImport.js
4。 Webhook
Webhook を使用すると、スケジュールではなくオンデマンドでデータを更新できます。これは、新しいイメージが Cloudinary に追加されるとすぐに、OCP データベースも更新されることを意味します。
OCPには「関数‘ これにより Webhook を作成できるようになります
関数の定義
関数を 'app.yml' ファイル。
1
2functions:
3 handle_new_asset:
4 entry_point: HandleNewAsset
5 description: Webhook that handles new assets uploaded to Cloudinary
関数を実装する
1import { logger, Function, Response } from '@zaiusinc/app-sdk';
2import { odp } from '@zaiusinc/node-sdk';
3import { transformNotificationToPayload } from '../lib/transformAssetToPayload';
4import { CloudinatyImageUploadNotification } from '../data/CloudinatyImageUploadNotification';
5
6export class HandleNewAsset extends Function {
7 1011
12 public async perform(): PromiseResponse> {
13
14 const notifcation = this.request.bodyJSON as CloudinatyImageUploadNotification;
15
16 if (!notifcation?.asset_id) {
17 return new Response(400, 'Unable to process request, invalid notification');
18 } else {
19 try {
20
21 const payload = transformNotificationToPayload(notifcation);
22 await odp.object('cloudinary_image', payload);
23
24 // return the appropriate status/response
25 return new Response(200);
26 } catch (e: any) {
27 logger.error(e);
28 return new Response(500, `An unexpected error occurred: ${e}`);
29 }
30 }
31 }
32}
新しいイメージが Cloudinary に追加されると、登録された Webhook が呼び出されます (「 'Lifecyce.ts')。次に、上記の関数を呼び出します。この関数は、Cloudinary ペイロードを読み取り、OCP データベースを更新します。
アプリケーションのデプロイ
アプリケーションをローカルで実行することはできません。 OCP プラットフォーム内でのみ実行できます。つまり、アプリケーションの機能を検証するには、包括的な単体テストを作成することが重要です。 OCP CLI はこれを予期しており、プロジェクト内で見つかったテストを実行します。 Jest テスト フレームワークは、アプリケーションがスキャフォールディングされるときにインストールされます。
最初は制限的に感じるかもしれませんが、単体テストと CLI 検証を組み合わせることで、展開を予測可能かつ再現可能にします。
アプリケーションをテストしてデプロイするには、次の手順に従う必要があります。
-
ocp app validate– 構成が検証され、すべての単体テストが実行されます。 -
ocp app prepare– アプリケーションは公開の準備ができています。 -
ocp directory publish [email protected]– アプリケーションを OCP に公開します。 -
ocp directory install [email protected] TRACKER_ID– アプリケーションをインスタンスにインストールします。
ログへのアクセス
アプリケーション内の「トラブルシューティング」タブには、ログに書き込んだメッセージが表示されます。

最後に
Optimizely Connect プラットフォームは、外部システムを Optimizely One エコシステムに統合するための堅牢で簡単なフレームワークを提供します。すでに Optimizely One を使用しているチームにとって、OCP は従来統合開発に関連していた運用上のオーバーヘッドの多くを除去します。
スキャフォールディングされたアプリに基づいた Cloudinary コネクタの開発は非常に迅速かつ簡単であることがわかりました。
アプリのソース コードは、私の GitHub リポジトリから入手できます。 https://github.com/andrewmarkham/Cloudinary/
#Optimizely #Connect #Platform #OCP #アプリを構築する方法