Developing custom embedded widget

Accessing context

Custom widgets have access to widget context, which can be utilised to personalise the widget content.

Widgets have access to the context, that has the following format.

{
    "token": "eyciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7InByaW1hc...",
  "scopedData": {
    "user": {
      "id": "123",
      "primaryEmail: "[email protected]"
    },
    "organisation": {
        "id": "234" 
    }
  },
  "context": {
    "hostname": "app.happeo.com",
    "href": "https://app.happeo.com/pages/xyz/...",
    "pathname": "/pages/xyz/..."
  }
}

Types of data

token
Token is a JWT which has been signed with the shared secret. The JWT contains the scopedData.

scopedData
This contains all the data that is given to this widget in the admin panel. Note that if no scopedData is requested, the token will also be empty.

context
This contains the necessary information to know where this widget is being shown.

Reading / requesting context

There are 2 ways of accessing context, reading and requesting.

Reading context

The easies way to access widget context is to read the iframe name -tag and parsing the result. Below is an example snippet:

const context = JSON.parse(window.name);

Requesting context

The other way to access context is to request it by postMessage. This requires the postMessage to include requested scope. The response requires listening of postMessages. Note the JSON format of the request and response:

Happeo listens to messages that have an object key _c and responds with object key _h.

(function () {
  function listener(event) {
    const { data } = event;

    if (!data._h || typeof data._h !== "object") {
      // This is not coming from Happeo
      return;
    }

    if (data._h.userinfo) {
      // Happeo sent us bunch of data, we should do stuff with it
      console.log(data._h);
    }
  }

  // Start listening to messages
  window.addEventListener("message", listener);

  // Post to Happeo your ID, the scope that you need and optionally you can call "resize" to set the parent iframe height
  window.parent.postMessage(
    { _c: { scopes: ["userinfo.email"], resize: "600" } },
    "*",
  );

  // Remember to call destroy when needed
  function destroy() {
    window.removeEventListener("message", listener);
  }
})();

Requesting widget resize

You can request the widget to resize to the desired height. This is done with the postMessage request. Note that this request still requires you to request a scope, so a blind "resize" requests are ignored. However you can, of course, just ignore the response sent by Happeo.

The resize is done by sending the following type postMessage to the window.parent. The resize is verified with isNaN so only numbers and stringified numbers are allowed. We consider all numbers to be px.

window.parent.postMessage(
    { _c: { scopes: ["userinfo.email"], resize: "600" } },
    "*",
  );

What if widget resize does not work

Potential resolutions:

  • Check that the widget has a scope allowed. If no scopes are allowed, all incoming postMessages are ignored.
  • The widget may not be allowed to resize in Pages. To check this, you need to verify that the widget settings have "Auto-height" set to true. This can be done by opening a page with the widget, selecting the widget and checking the checkbox on the edit -panel.
824824

What’s Next