Hooks

Skills can anchor hooks with adapters that implements them. They can register a new Hook using the skill.createHook() method. The creator can add a third parameter ( a string ), to specify the string that the adapter will return when closing this hook, example : "This hook can be called only once !". This will return a Promise to the created hook. The hook will not be valid, and the adapter must confirm before it can be executed. To request a hook, the message object returned by the skill must contain request_hook: true and hook: <hook>. Adapters should understand the request when parsing the message, and will validate the hook. Then, the skill will be able to execute the hook with skill.useHook(hook_id, message) (which is a Promise). The creator can add a third parameter : {deleteHook: true} to delete the hook after it execution.

Nota Bene: It is the responsability of the skill to handle Promise rejections with personnalized error messages.

When executing a hook, in case of an error, you will receive an error code that you can use to update your skill's storage. For instance, if you catch NO_HOOK, it means the Hook was deleted by the hub, or NO_CONNECTOR_LINKED if no connector accepted the hook, or NO_CONNECTOR_ONLINE if the linked connector could not be reached.

Example

In this example, we request a new Hook and set a alarm that will display a message in the channel.

module.exports = (skill) => {
  const schedule = skill.loadModule("node-schedule");

  skill.setDescription("Set and manage alarms.");

  /*
   * Will not persist the alarm, we should add the alarm to the storage here.
   */
  skill.addCommand("alarm", "set-alarm", ({ phrase, data }) => {
    return Promise.resolve().then(() => {
      let time = new Date();
      let text = "";

      try {
        const [timeString, ...textArray] = phrase.split(" ");
        text = textArray ? textArray.join(" ") : "";

        let [hours, minutes] = timeString.split(/[:h\-]/i);
        hours = parseInt(hours, 10);
        minutes = parseInt(minutes, 10);
        if (isNaN(hours) || hours < 0 || hours > 24) {
          throw "Invalid hour format.";
        }
        if (isNaN(minutes) || minutes < 0 || minutes >= 60) {
          throw "Invalid minutes format.";
        }
        time.setHours(hours, minutes, 0, 0);


        return skill.createHook("Alarm rang, hook removed.").then(hook => {
          schedule.scheduleJob(time, () => {
            skill.useHook(hook._id, {
              message: "Alarm",
              text: text
            }, { deleteHook: true }).catch(err => skill.log(err));
          });

          return {
            message: {
              text: "Alarm set!"
            }
          }
        });
      } catch (e) {
        return {
          message: {
            title: "Invalid time format.",
            text: "Type `!alarm hh:mm` to create a new alarm."
          }
        }
      }


    });
  }, {
    description: "Set a one-time alarm.",
    parameters: [
      {
        position: 0,
        name: "time",
        example: "16:40",
        description: "Time to set the alarm"
      },
      {
        position: 1,
        name: "text",
        example: "It's tea time!",
        description: "Text to send with the alarm."
      }
    ]
    examples: [
      {
        phrase: "!alarm 16h Tea Time!",
        action: "Will say 'Tea Time!' in the channel at 16h00."
      }
    ]
  });
}

results matching ""

    No results matching ""