Add the SDK

Script tag

Add the SDK and CSS. This loads the main object Versori to the global window scope of the browser.

title="index.html"
<head>
  ...
  <script
    src="https://assets.versori.io/a/hubs/sdk/1.0.0/index.mjs"
    type="module"
    crossorigin
  ></script>
  <link
    rel="stylesheet"
    href="https://assets.versori.io/a/hubs/sdk/1.0.0/style.css"
  />
</head>

Initialise SDK

The SDK main Object provides an initialise function, accepting an object of options.

title="/src/components/integrationComponent.js"
function IntegrationComponent(props) {
  window.Versori.initHubs({
    userId: [USER_ID],
    orgId: [ORGANISATION_ID],
    apiKey: [YOUR_READ_API_KEY],
    finaliseTo: [YOUR_ENDPOINT],
    onConnected: (connection, connectionInfo) => {},
    onDisconnected: (connectionInfo) => {},
    onCompleted: () => {},
    onError: (error) => {
      console.log(error.message, error.description);
    },
    onInitialised: () => {},
  });
}

Options

userId (type: string, required: true)

The user ID for the current logged in user.

orgId (type: string, required: true)

The organisation ID for your Versori platform subscription where your Hubs are located.

apiKey (type: string, required: true)

A read-only public API Key set in your organisation settings inside Versori platform.

finaliseTo (type: string, optional: true)

The finaliseTo option is intended to be used as a direct url the SDK can POST connection details to after a connection has been made.

An example of this might be https://clientUrl/api/receiveConnectionDetails, where connection information will be sent directly.

onCompleted (type: Function, optional: true)

The onCompleted callback is called if a finaliseTo url is provided to a POST endpoint and the request was succesful. Here is where Frontend updates and any subseuqent processes can be handled.

onConnected (type: Function, optional: true)

The onConnected callback is used to return the connection details to the frontend after a connection is made to the integration. Returns App credential details and contextual information for Hub, Board and connected App.

Warning: The SDK is intended to be used with one of either option - finaliseTo or onConnected. If finaliseTo is provided it will take precedence and the onConnected callback will not be called. If you require control over how the information is sent to your Backend then the onConnected callback would be the preferred option.

onDisconnected (type: Function, required: true)

The onDisconnected callback can be used to trigger a request to your backend where a request to the Versori DELETE user endpoint can be made. Returns the Hub ID and Board ID.

onError (type: Function, required: true)

The onError callback is triggered at any point in the flow when an error would prevent a connection being made. Useful to communicate to the user an error has occured.

onInitialised (type: Function, optional: true)

The onInitialised callback is called when the SDK has completed its mounted setup and the SDK is ready. Here is where any Front end updates dependant on the SDK being available can be handled.


To Connect

Connections are triggered from elements containing specific data-attributes.

Below is an example of the data-attributes that are required per integration. What type of element you use is up to you, the important part is the data-attributes.

title="frontend/src/components/integrationComponent.js"
function IntegrationComponent(props) {
    ...
    return (
        <button
            data-vhubs
            data-vhubid=[YOUR_HUB_ID]
            data-vhubboardid=[YOUR_BOARD_ID]
        >
            Connect
        </button>
    );
}

UI handling

You will be responsible to update the UI after a user has been created or deleted. It is required a [data-connected] attribute be set/unset on the element. Internally, on initalisation, the SDK sets a [data-connected] attribute, for each already connected integration, on the element you have provided the required hub and board data-attributes on.

Warning: It is imperative the [data-connected] is toggled on create/delete. The SDK uses this attribute to trigger the correct flow from the event.

Below is an example of how UI updates could be handled in React.

title="frontend/src/components/integrationComponent.js"
function IntegrationComponent(props) {
    ...
    useEffect(() => {
        window.Versori.initHubs({
            ...
            onConnected: async (connection, connectionInfo) => {
                try {
                    // Make call to Backend and then createUser in Versori
                    const response = await callToYourBackend()
                    if (response.ok) {
                        handleButtonUpdate(connectionInfo.boardId)
                    }
                } catch(e) {
                    // Handle errors
                    console.log(e)
                }
            },
            onDisconnected: async (connectionInfo) => {
                try {
                    // Make call to Backend and then deleteUser in Versori
                    const response = await callToYourBackend()
                    if (response.ok) {
                        handleButtonUpdate(connectionInfo.boardId)
                    }
                } catch(e) {
                    // Handle errors
                    console.log(e)
                }
            }
        })
    }, [])


    const handleButtonUpdate = (boardId) => {
        // toggle [data-connected] on the element matching boardId and handle any other desired UI updates
    }

    return (
        ...
        <button
            data-vhubs
            data-vhubid=[YOUR_HUB_ID]
            data-vhubboardid=[YOUR_BOARD_ID]
        >
            Connect
        </button>
    );
}

Valid Authentication types

The Versori Hubs SDK supports OAuth2 (oidc), API Key, and Basic authentication (username, password).


Create User for Integration

Once a user has authenticated to the Integration, the onConnected callback will provide connection information that you can use when sending a request to your Backend to authenticate the user in your system before then sending a PUT request to the Versori create user endpoint.

https://platform.versori.com/apis/hubs-sdk/v1/organisations/{orgId}/hubs/{hubId}/boards/{boardId}/users/{userId}

WARNING: From a system architecture decision, we do not support email as a unique userId. Characters pertaining to the regex \A[-/_=.a-zA-Z0-9]+\z are valid.

Note: Providing a finaliseTo endpoint will send connection details directly to your Backend and the onConnection callback will not be triggered.

title="backend/src/services/user/createUser.js"
app.post('/backendCreateUserEndpoint', (req, res) => {
    const { orgId, hubId, boardId } = req.body
    let body = req.body

    // Optional: Extend body with any extra environments and dynamic variables.

    const reponse = fetch(`https://platform.versori.com/apis/hubs-sdk/v1/organisations/{orgId}/hubs/{hubId}/boards/{boardId}/users/{userId}`, {
        method: 'PUT',
        headers: {
            Authorization: `Bearer [YOUR_WRITE_API_KEY]`,
        },
        body: JSON.stringify(body)
    })
    const data = await response.json();

    console.log(data);
})

Create User request body structure

    {
        environments: [
            {
                connectionId: [CONNECTION_ID],
                credentialId: [CREDENTIAL_ID],
                key: [APP_KEY],
                variables: {
                    [KEY]: [VALUE]
                },
            },
        ],
        id: userId,
        variables: {
            [KEY]: [VALUE]
        },
    }

As the user, you are required to set any variables in the create user request body. Variables is an object of key value pairs.

    variables: {
        key: value
    }

Please note: variables must match what has been set for the dynamic variables in the associated Hub Board in the Versori UI.


Disconnect User from Integration

To disconnect a user, the onDisconnected callback can be used to send a POST request to your Backend before sending a DELETE request to the Versori delete user endpoint

https://platform.versori.com/apis/hubs-sdk/v1/organisations/{orgId}/hubs/{hubId}/boards/{boardId}/users/{userId}

WARNING: From a system architecture decision, we do not support email as a unique userId. Characters pertaining to the regex \A[-/_=.a-zA-Z0-9]+\z are valid.

title="backend/src/services/user/deleteUser.js"
app.post('/backendDeleteUserEndpoint', (req, res) => {
    const { orgId, hubId, boardId } = req.body
    const reponse = fetch(`https://platform.versori.com/apis/hubs-sdk/v1/organisations/{orgId}/hubs/{hubId}/boards/{boardId}/users/{userId}`, {
        method: 'DELETE',
        headers: {
            Authorization: `Bearer [YOUR_WRITE_API_KEY]`,
        },
    })
    const data = await response.json();

    console.log(data);
})

Destroy

The SDK exposes a destroy function on the window Versori object that will delete the SDK and remove all event listeners.

title="/src/components/integrationComponent.js"
function IntegrationComponent(props) {
  window.Versori.destroy();
}