Server Code を実行するトリガー

Server Code を自動実行する場合、自動実行される Server Code の情報と、実行条件をトリガーに設定します。

Server Code が実行された後、その実行結果(エラーの有無や戻り値)を取得することもできます。

ステート条件のトリガーの登録

トリガーの登録を行う前に、Server Code を設置しておきます。設置方法は、サーバー機能拡張リファレンスガイド をご覧ください。

Server Code を設置した後、呼び出したいエンドポイントの情報をトリガーに設定します。

ここでは、「室温が 30 度以上の時、Server Code の alertTemperature エンドポイントを、パラメータ {"caller":"trigger"} で実行する」というトリガーの登録例を示します。

  • // Specify an end point of server code.
    const accessToken = kii.KiiUser.getCurrentUser().accessToken
    const param = {"caller": "trigger"}
    const serverCode = new ThingIF.ServerCode("myFunction", accessToken, null, param)
    
    // Create a predicate.
    // Execute the server code when the temperature is greater than or equal to 30 deg C.
    const condition = new ThingIF.Condition(ThingIF.Range.greaterThanEquals("currentTemperature", 30));
    const predicate = new ThingIF.StatePredicate(condition, ThingIF.TriggersWhen.CONDITION_FALSE_TO_TRUE);
    
    // Create a trigger request.
    const request = new ThingIF.PostServerCodeTriggerRequest(serverCode, predicate);
    
    // Send a trigger.
    api.postServerCodeTrigger(request).then((trigger: ThingIF.Trigger) => {
      // Do something.
    }).catch((error: ThingIF.ThingIFError) => {
      // Handle the error.
    });
  • // Specify an end point of server code.
    var accessToken = KiiUser.getCurrentUser().accessToken
    var param = {"caller": "trigger"}
    var serverCode = new ThingIF.ServerCode("myFunction", accessToken, null, param)
    
    // Create a predicate.
    // Execute the server code when the temperature is greater than or equal to 30 deg C.
    var condition = new ThingIF.Condition(ThingIF.Range.greaterThanEquals("currentTemperature", 30));
    var predicate = new ThingIF.StatePredicate(condition, ThingIF.TriggersWhen.CONDITION_FALSE_TO_TRUE);
    
    // Create a trigger request.
    var request = new ThingIF.PostServerCodeTriggerRequest(serverCode, predicate);
    
    // Send a trigger.
    api.postServerCodeTrigger(request).then(
      function(trigger) {
        // Do something.
      }
    ).catch(
      function(error) {
        // Handle the error.
      }
    );

ここでは、ServerCode インスタンスと StatePredicate インスタンスを作成し、postNewTrigger メソッドでトリガーの登録を行っています。

ServerCode インスタンスによって、Server Code の実行条件を指定します。ServerCode のコンストラクタには、以下のパラメータを指定できます。

  • 第 1 引数:実行される Server Code のエンドポイント名(JavaScript の関数名)を指定します。
  • 第 2 引数:Server Code を実行する際のアクセストークンを指定します。ここではオーナーユーザーのアクセストークンを指定しています。Server Code では、context.getAccessToken() によって、呼び出し元のアクセストークンを取得して、そのユーザーの権限で処理を実行できます。トリガーから起動された場合は、ここで指定したアクセストークンが取得されます。
  • 第 3 引数:Server Code がある Kii Cloud アプリケーションの AppID を指定します。トリガーでは自分以外のアプリケーションにある Server Code を呼び出すことができますが、同じサーバー設置場所に存在している必要があります。null を指定した場合は、api を初期化したのと同じアプリケーションの Server Code を呼び出します。
  • 第 4 引数:エンドポイントに渡すパラメータを指定します。パラメータが不要な場合は null を指定します。

トリガー実行条件の初期化方法は コマンドの自動実行の場合と同じです。

トリガーを登録すると、結果として Trigger インスタンスを取得できます。

Server Code の実行結果の取得

Server Code の実行結果を取得することができます。トリガーを設定後、実行条件を満たすステートが登録されるごとに Server Code が実行され、その結果は Thing Interaction Framework 内に蓄積されていきます。この結果は API を通して取得することができます。

登録されている実行結果が多数ある場合は、ページネーションを利用します。たとえば、実行結果が 30 件登録されている場合、10 件をページとして、10 件ずつ 3 回に分けて取得することができます。

以下にサンプルコードを示します。

  • const callback = (error: Error, results: ThingIF.QueryResult<ThingIF.ServerCodeResult>)=> {
      if (error) {
        // Handle the error.
        return;
      }
    
      for (const serverCodeResult of results.results) {
        // Check if the server code succeeded or not and process each result.
        if (serverCodeResult.succeeded) {
          const returnedValue: Object = serverCodeResult.returnedValue;
          const executedAt: number = serverCodeResult.executedAt;
          const endpoint: string  = serverCodeResult.endpoint;
        } else {
          const serverError = serverCodeResult.error;
          const errorCode: string = serverError.errorCode;
          const errorMessage: string = serverError.errorMessage;
          const detailMessage: string = serverError.detailMessage;
          const executedAt: number = serverCodeResult.executedAt;
          const endpoint: string  = serverCodeResult.endpoint;
        }
      }
    
      // If the next page exists
      if (results.paginationKey) {
        // Get the next page of the list.
        api.listServerCodeExecutionResults(trigger.triggerID, new ThingIF.ListQueryOptions(null, results.paginationKey), callback);
      }
    };
    
    // Get a list of server code results.
    api.listServerCodeExecutionResults(trigger.triggerID, new ThingIF.ListQueryOptions(10), callback);
  • var callback = function(error, results) {
      if (error) {
        // Handle the error.
        return;
      }
      for (var i = 0; i < results.results.length; i++) {
        var serverCodeResult = results.results[i];
        // Check if the server code succeeded or not and process each result.
        if (serverCodeResult.succeeded) {
          var returnedValue = serverCodeResult.returnedValue;
          var executedAt = serverCodeResult.executedAt;
          var endpoint  = serverCodeResult.endpoint;
        } else {
          var serverError = serverCodeResult.error;
          var errorCode = serverError.errorCode;
          var errorMessage = serverError.errorMessage;
          var detailMessage = serverError.detailMessage;
          var executedAt = serverCodeResult.executedAt;
          var endpoint  = serverCodeResult.endpoint;
        }
      }
    
      // If the next page exists
      if (results.paginationKey) {
        // Get the next page of the list.
        api.listServerCodeExecutionResults(trigger.triggerID, new ThingIF.ListQueryOptions(null, results.paginationKey), callback);
      }
    };
    
    // Get a list of server code results.
    api.listServerCodeExecutionResults(trigger.triggerID, new ThingIF.ListQueryOptions(10), callback);

ここでは listServerCodeExecutionResults メソッドによってサーバーに登録された実行結果を一覧取得しています。取得の際には、Server Code を登録した際に取得した Trigger クラスのインスタンス trigger が持つトリガーの ID が必要です。

listServerCodeExecutionResults メソッドは Promise にも対応していますが、全件取得するには再帰によるループ構造を作成する必要があるため、コールバック関数によるサンプルコードとしています。Promise によってループを実現する方法は、KiiObject の検索 の実装例などを参考にしてください。

ListQueryOptions の第 2 引数によって、現在のページの状態を表します。初めにページネーションキーの指定なしで listServerCodeExecutionResults メソッドを呼び出すと、先頭ページが取得でき、コールバック関数の引数の paginationKey として次のページネーションキーが返されます。これを次の listServerCodeExecutionResults のページネーションキーとして指定すると、そのページを取得できます。最終的に全件取得されると、ページネーションキーは undefined を返します。

ListQueryOptions の第 1 引数は 1 回に取得する実行結果の件数です。指定しないか null を指定すると、サーバー側での自動設定になります。ページのサイズは Best Effort のため、値を指定しても、一度に指定件数分を取得できないことがあります。取得できなかった実行結果は、次のページで取得できます。

ハンドラーの引数の results に取得できた実行結果の一覧が入っています。コード例にあるように、成功したかどうか、実行した日時、エンドポイント名(Server Code の関数名)、成功時はその実行結果、失敗時はエラーの詳細情報をそれぞれ取得することができます。