miibo JSの実装
miibo JSの記述
以下に、miibo JS(miibo Custom Action専用の JavaScript 実行環境)向けの実装ガイドを掲載します。
Custom Actionのコードを実装する際の参考にしてください。
1. コーディング規約 (Style Guide)
1.1 基本構文
-
セミコロンの明示
- JavaScript にはセミコロンの挿入機能 (ASI) がありますが、可読性のためにも行末でのセミコロン使用を推奨します。
-
変数宣言
let
やconst
を使用してください。グローバルスコープやブロックスコープの意図しない露出を防ぎます。const result = {}; let count = 0;
-
関数宣言
- 関数を定義するときは、使い方に応じて関数宣言・アロー関数を使い分けます。
- ただし、非同期処理 (
async/await
など) は使用できません。
-
命名規則
- キャメルケースを推奨: 例)
getUserData()
,searchResult
,currentCount
- 定数や設定値など変更されないものは大文字スネークケースを推奨: 例)
const API_URL = "https://example.com";
- キャメルケースを推奨: 例)
-
エラー処理
- エラーを投げる際は
throw new Error(...)
を使用し、呼び出し元またはスクリプト内で必ず捕捉 (catch) してください。 - 明確なメッセージを設定するとトラブルシューティングが容易になります。
- エラーを投げる際は
-
コメント
- 複雑なロジックや意図が分かりづらい箇所にはコメントを入れてください。
- 関数の概要などは JSDoc スタイルのコメントを使用すると可読性が向上します。
1.2 スクリプト構造
-
単一スクリプトとしての実行
- 1つの JavaScript ファイルがそのまま 1つの “Custom Action” として扱われます。
- スクリプトの最後でオブジェクトや値を「return」なしで記述します。
-
グローバルスコープの
this
はundefined
- ブラウザ環境のような
window
やdocument
、Node.js のようなrequire
やprocess
は利用できません。
- ブラウザ環境のような
-
同期実行のみ
Promise
,async/await
,setTimeout
,setInterval
は使用できません。fetch
を含む I/O も同期的に結果を返します。
-
モジュールシステムは使用不可
import
,export
,require
などは使わず、単一ファイルで完結してください。
-
最後に記述した変数が呼び出し元に返る
- スクリプト実行後、最後に記述された変数がレスポンスとして返されます。
2. マニュアル (Usage Guide)
2.1 実行環境と変数
-
入力オブジェクト
input
- 外部から渡されるパラメータが格納されており、必要に応じてバリデーションが必須です。
- 例:
input.query
,input.userId
など。
-
環境変数オブジェクト
env
- カスタムアクションで使用する API キーやエンドポイントなどが格納されています。
- 例:
env.API_KEY
,env.SLACK_WEBHOOK
,env.SLACK_CHANNEL_ID
など。
-
ファイル I/O や OS コマンドの実行は不可
- ファイルシステムや OS コマンドとのやりとりはサポートされません。
2.2 同期的な fetch(url, options)
の使用方法
fetch(url, options)
の使用方法fetch
は一見ブラウザの API に似ていますが、同期的に結果が返ります。- 戻り値の
response
は以下の形式です:
{
status: Number, // HTTPステータスコード (例: 200, 404...)
headers: Object, // レスポンスヘッダー
body: Object | String // Content-Type が JSON の場合はパース済みオブジェクト、それ以外は文字列
}
例: POST リクエスト
const response = fetch('https://example.com/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ foo: 'bar' })
});
if (response.status >= 200 && response.status < 300) {
// 成功
} else {
// エラー扱い
throw new Error(`Request failed with status ${response.status}`);
}
注意:
response.ok
のプロパティはありませんので、必ずresponse.status
で判定してください。
2.3 エラー制御
- ネットワーク障害などでリクエストが失敗すると、
fetch
が例外 (throw
) を発生させます。 - スクリプト全体の処理が中断されるため、必ず
try-catch
で例外を捕捉することを推奨します。
try {
const response = fetch('https://example.com/api');
if (response.status !== 200) {
throw new Error(`Request failed: HTTP ${response.status}`);
}
// 成功時の処理...
} catch (err) {
return { success: false, error: err.message };
}
2.4 実行時制限・注意点
-
同期実行のみ
- 非同期構文 (
Promise
,async/await
) は利用不可。 - 大量データや長時間処理があるとブロックが発生します。
- 非同期構文 (
-
ブラウザや Node.js と異なる環境
window
,document
,File
,localStorage
等はありません。- 同様に、Node.js 特有の
process
,require
,Buffer
も使用できません。
-
メモリやCPUの使用量に注意
- 過度な大規模ループや巨大オブジェクトの生成は避けてください。
-
エラー発生時の挙動
- 例外が投げられるとスクリプトが中断されます。必要に応じて
try-catch
で制御を行い、適切にエラー内容を返す実装を行ってください。
- 例外が投げられるとスクリプトが中断されます。必要に応じて
3. サンプルコード
3.1 Web Search APIを叩くサンプル
const result = {
success: false,
messages: [],
error: null
};
try {
// 入力値のバリデーション
if (!input.query) {
throw new Error('Query is required');
}
// 環境変数の検証
if (!env.API_KEY) {
throw new Error('API key is not configured');
}
if (!env.SEARCH_ENGINE_ID) {
throw new Error('Search Engine ID is not configured');
}
// APIリクエスト用の情報
const url = 'https://example-miibo.com/web/search';
const payload = {
engine: env.SEARCH_ENGINE_ID,
query: input.query,
apiKey: env.API_KEY,
getCount: 1
};
const response = fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (response.status !== 200) {
throw new Error(`API request failed: ${response.status}`);
}
result.success = true;
result.messages = [
'API request succeeded',
JSON.stringify(response.body)
];
} catch (err) {
result.error = err.message;
}
result;
3.2 Slackにポストするサンプル
// Slack Webhookに通知する例
// env.SLACK_WEBHOOK を使ってfetchします。
const response = fetch(env.SLACK_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: '[通知] Hello from Miibo!' })
});
if (response.status >= 200 && response.status < 300) {
return { success: true };
} else {
return { success: false, status: response.status };
}
3.3 Slackのメッセージを取得するサンプル
const result = {
success: false,
messages: [],
error: null
};
try {
if (!env.SLACK_BOT_TOKEN) {
throw new Error('Missing SLACK_BOT_TOKEN in env');
}
if (!env.SLACK_CHANNEL_ID) {
throw new Error('Missing SLACK_CHANNEL_ID in env');
}
const response = fetch('https://slack.com/api/conversations.history', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.SLACK_BOT_TOKEN}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `channel=${env.SLACK_CHANNEL_ID}&limit=100`
});
if (response.status !== 200) {
throw new Error(`Failed to fetch messages: HTTP ${response.status}`);
}
// Slack API が JSON で応答する想定
const data = response.body;
// 必要に応じて応答フォーマットをチェック
// (response.body 内が期待する構造であるかを確認)
// 例えば messages フィールドがあればそれを取り出す
if (!data.messages) {
throw new Error('No messages field found in response');
}
result.success = true;
result.messages = data.messages;
} catch (err) {
result.error = err.message;
}
result;
4. その他の考慮点
- レスポンスサイズ
- レスポンスが大きいとメモリ使用量が増加し、処理が重くなります。必要最小限に留めてください。 (目安は1MB以内です。今後、サイズが大きいレスポンスには制限が発生する可能性があります。)
- バージョン管理
- スクリプトの更新履歴を追えるよう、Git 等によるバージョン管理を推奨します。 (現在、miiboではバージョン管理のサポートを行っていません。)
5. まとめ
- 同期実行ベースの JavaScript 環境であることを理解し、
fetch
や I/O を行う際にはブロックが発生する点に注意が必要です。 input
/env
から必要な値を取得し、console.log
でログ出力・デバッグが可能です。- エラー時は
try-catch
で制御し、ステータスコードが想定通りかどうかをresponse.status
で判定しましょう。 - 最後にオブジェクトや値を記述すると、呼び出し元がその値を受け取れる仕組みになっています。
以上のガイドラインを守ることで、保守性・可読性の高いカスタムアクションを作成できます。
Updated 2 months ago
Did this page help you?