# スクリプトの構造

> Understand the structure of a Cloud Code script and how the main function acts as the entry point.

ランタイムのエントリーポイントとして機能する Cloud Code スクリプトのメイン関数は、CommonJS ラッパーの形式をとります。

以下のコードスニペットは、可能なかぎり最も単純なスクリプトを示します。

*JavaScript*

```js
module.exports = async ({ params, context, logger }) => {
  // this script does nothing
};
```

このスクリプトは実際には何も行いませんが、スクリプト関数のコンテキストオブジェクトと非同期の性質を示します。

> **Note:**
>
> **ノート**: スクリプトは、CommonJS 関数をエクスポートしないかぎり無効です。

> **Note:**
>
> **ノート**: スクリプト名はプロジェクトと環境全体で一意である必要があり、文字、数字、アンダースコア、ダッシュのみ使用でき、50 文字を超えることはできません。

## コンテキストオブジェクト##context-object

コンテキストオブジェクトには、以下の有用なオブジェクトが含まれます。

* `Params`: これは、スクリプトが呼び出されるときに使用される入力パラメーターの名前と値のペアの配列です。

* `Context`: このオブジェクトは、スクリプト内で役立つ追加のコンテキストを提供します。

  * `projectId`: 呼び出し元が認証されたプロジェクト ID。
  * `playerId`: 認証されたプレイヤー ID。
  * `accessToken`: 他の Unity ゲームサービス SDK を認証されたプレイヤーとして呼び出すために使用できる JWT。
  * `environmentName`: 現在使用されている Unity [環境](/services/service-environments.md) の名前。
  * `environmentId`: 現在使用されている Unity 環境の ID。
  * `serviceToken`: 他の Unity ゲームサービス SDK を認証された Cloud Code ユーザーとして呼び出すために使用される JWT。
  * `unityInstallationId`: クライアントのデバイス上のインストールを識別する一意の識別子。異なるデバイスにゲームをインストールしている場合は、同じプレイヤーが異なる `installationId` を持つ可能性があります。Services SDK Core パッケージと統合されるすべての Unity パッケージで使用可能です。
  * `analyticsUserId`: プレイヤーを識別する一意の文字列で、分析を目的として後続のプレイセッションで一貫して使用されます。これはプライマリユーザー識別子であり、Core パッケージから取得されます。
  * `correlationId`: リクエストを関連付けるために使用される一意の識別子。

* `Logger`: スクリプトが情報、警告、エラーをログに記録できるようにするオブジェクト。

### JavaScript##javascript

```js
module.exports = async ({logger}) => {
  logger.info('This message confirms that the logging client is functional!');
  logger.warning('This is a serious warning that the cheese is about to run out.');
  logger.error('Out of cheese :(');
}
```

詳細については、[ロギング](../../logging/overview) のドキュメントを参照してください。

### トークン認証##token-authentication

`accessToken` と `serviceToken` は、`context` オブジェクトのプロパティとして提供される [JWT](https://jwt.io/) です。

これらのトークンは、Cloud Code から他の Unity Gaming Services の呼び出しを認証します。

| トークンタイプ        | 発生元                                                  | データアクセス                | 使用方法                                                                                       |
| -------------- | ---------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------ |
| `accessToken`  | [Authentication サービス](/authentication.md) によって生成されます | 認証されたプレイヤーに限定されます      | `accessToken` は、Cloud Code 呼び出しの認証に使用される JWT です。これを他の UGS サービスに渡して、認証されたプレイヤーのデータにアクセスできます |
| `serviceToken` | Cloud Code によって生成されます                                | クロスプレイヤーデータアクセスを可能にします | `serviceToken` は Cloud Code によって生成されるトークンであり、他の UGS サービスを呼び出し、クロスプレイヤーデータを操作するために使用できます。   |

設定した [アクセス制御](./access-control.md) ルールは `accessToken` に影響します。

以下は、`accessToken` を使用して Economy SDK を呼び出し、プレイヤーのインベントリを取得する方法の例です。

#### JavaScript##javascript

```js
// Player inventory
const { InventoryApi } = require("@unity-services/economy-2.4");

module.exports = async ({params, context, logger}) => {
 const { projectId, playerId, accessToken } = context;
 const inventory = new InventoryApi({accessToken});
 const result = await inventory.getPlayerInventory({projectId, playerId});
 return result.data;
}
```

`serviceToken` を使用する場合、同じスクリプトは以下のようになります。

#### JavaScript##javascript

```js
// Player inventory
const { InventoryApi } = require("@unity-services/economy-2.4");

module.exports = async ({params, context, logger}) => {
const { projectId, playerId } = context;
const inventory = new InventoryApi(context);
const result = await inventory.getPlayerInventory({projectId, playerId});
return result.data;
}
```

2 つのトークンの違いの詳細な説明は、[サービスとアクセストークン](./token-support.md) を参照してください。

## スクリプトパラメーター##script-parameters

スクリプトパラメーターは、スクリプト本文の外部または内部で定義できます。

> **Note:**
>
> **ノート**: スクリプト内パラメーターは、パラメーターを宣言するためのよりシンプルな代替方法を提供しますが、Deployment パッケージを使用せずに更新しようとした場合、Unity Dashboard は現在スクリプト内パラメーターを解析しません。

### スクリプト内パラメーター##in-script-parameters

スクリプト内パラメーターは、各パラメーター名をキーとして、型を値として含む `params` オブジェクトをエクスポートすることで追加できます。

> **Important:**
>
> **重要**: パラメーターを設定する前に `module.exports` プロパティを割り当てる必要があります。

例を次に示します。

#### JavaScript##javascript

```js
module.exports.params = { "echo" : "Boolean" }
```

または、パラメーターが必須であることを指定したい場合は、`type` と `required` の両方のプロパティを含むオブジェクトを指定できます。

#### JavaScript##javascript

```js
module.exports = async ({ params, context, logger }) => {
    return {
        "value": params["aParam"]
    };
};

module.exports.params = { "aParam" : { "type": "String", "required": true } }
```

デフォルトでは、パラメーターは必須ではありません。

どちらの形式も希望に応じて組み合わせることができます。

#### JavaScript##javascript

```js
module.exports = async ({ params, context, logger }) => {
    var value = params["echo"] ? params["aParam"] : "default";
    return {
        "value": value
    };
};

module.exports.params = {
  "echo" : "Boolean",
  "aParam" : { "type": "String", "required": true }
 }
```

## async/await##asyncawait

メインスクリプト関数は、非同期関数にすることができます。これは、関数が await promise を実行できることを意味します。これにより、スクリプト内で他の Unity ゲームサービス SDK を使用できるようになります。[promise](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises) について説明している Mozilla ドキュメントを確認してください。

簡単な例は以下のようになります。

### JavaScript##javascript

```js
// Player inventory
const { InventoryApi } = require("@unity-services/economy-2.4");

module.exports = async ({params, context, logger}) => {
 const { projectId, playerId } = context;
 const inventory = new InventoryApi(context);
 const result = await inventory.getPlayerInventory({projectId, playerId});
 return result.data;
}
```

> **Note:**
>
> **ノート**: Cloud Code クライアントサイド呼び出しは常に非同期であり、通常 (同期) スクリプトと非同期スクリプトの両方があります。

## その他のパッケージ##additional-packages

スクリプトは、`import` または `require` キーワードを使用してローカルスクリプトまたは外部パッケージをインポートできます。

インポートできるものの完全なリストについては、[利用可能なパッケージ](../reference/available-libraries) を参照してください。

### JavaScript##javascript

```js
const _ = require("lodash-4.17");

module.exports = async () => {
  return _.random(1, 6);
};
```

> **Note:**
>
> **ノート**: 必要なパッケージは、エクスポートされる関数の外部で宣言する必要があります。

## バンドル##bundling

> **Note:**
>
> **ノート**: Unity Dashboard と CLI は、現在バンドルされたスクリプトを完全にはサポートしていません。

スクリプトバンドルは、Unity エディター内で Deployment パッケージを使用して有効化される機能であり、ローカルでのスクリプトの管理、追加のワークフローのロック解除、複数のスクリプト間で共有する一般的な機能の有効化に役立ちます。バンドルされたスクリプトの生成方法について詳しくは、[JS バンドル](./write-scripts/unity-editor.md#js-bundles) のドキュメントを参照してください。

### JavaScript##javascript

```js

const lib = require("./lib");

module.exports = async () => {
  return lib.helloWorld();
};

module.exports.bundled = true;
```

## 出力##output

スクリプトの出力は、以下の型から構成できます。

### JavaScript##javascript

* `string`
  ```js
  module.exports = async () => {
    return "hello world";
  };
  ```
* `boolean`
  ```js
  module.exports = async () => {
    return true;
  };
  ```
* `number`
  ```js
  module.exports = async () => {
    return 3.14;
  };
  ```
* `object`
  ```js
  module.exports = async () => {
    return {
      message: "hello world",
      success: true
    };
  };
  ```

正常なレスポンスは、API から以下の構造を持つ JSON として返されます。

```text
{
  "output": <SCRIPT OUTPUT>
}
```

### エラー出力##error-output

エラーは、何かが呼び出しの失敗の原因となった場合に (例えば、失敗したサービスリクエスト)、スクリプトによってスローされることがあります。

スクリプト内でエラーを捕捉すると、失敗を処理する方法を決定できます。

#### JavaScript##javascript

```js
module.exports = async ({logger}) => {
  try {
    let result = service.call("example");
    return result;
  } catch (err) {
    logger.error("Something went wrong!", {"error.message": err.message});
    throw err;
  }
};
```

エラーレスポンスは、エラータイプ、エラーメッセージ、およびエラーの原因を特定するのに役立つスタックトレースとともに、API から JSON として返されます。

```text
{
  "type": "problems/invocation",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Invocation Error",
  "instance": null,
  "code": 9009,
  "details": [
      {
          "name": "ReferenceError",
          "message": "service is not defined",
          "stackTrace": [
              "at module.exports (example-test.js:1:26)"
          ]
      }
  ]
}
```
