HomeCustomise & extendDynamic content pages with the Page Composer API

Dynamic content pages with the Page Composer API

Use the Page Composer API to publish content to an Interact page automatically from an external system on a schedule.

Before you start

  • You need a dedicated user account for API connectivity.
  • You need the API domain and tenant GUID for your intranet instance.

Note: The boilerplate in this guide is a sample, not officially supported by Interact Technical Support. Review and test it with your development team before use.

Overview

The Interact API can be used to keep a page on your intranet updated, or synced, with content generated from an external system. This guide uses the Page Composer API to create a cronjob-like sync that publishes dynamic data to Interact.

Common use cases

  • Leaderboards
  • Progress updates
  • Employee recognition
  • Automatic analysis and forecast publishing
  • KPIs
  • Graphs, charts and metrics
  • Sales progress
  • Project burndowns and recurring updates
  • Data dumps from external systems wrapped in HTML

Tutorial

The boilerplate is provided in .NET Framework/Core C# (RestSharp). You can convert it to any language or system capable of pushing content to REST API endpoints.

Application flow

  1. Get the API domain for your Interact instance.
  2. Authenticate using the Basic Authentication flow.
  3. Create HTML content, manually or dynamically using another process.
  4. Push the generated content to the Page Composer API.

Step 1: Find the API domain

Interact provides an endpoint to get details about your intranet instance. Find your API domain by going to https://your-intranet.interactgo.com/info. This lists the following details in JSON format:

  • API domain (required)
  • Auth mode
  • Tenant GUID (required)
  • Name
  • Market API path

You need the API domain and tenant GUID. With these, you can begin authentication.

// Required for API
string apiDomain = "https://us-lb-api-01.interactgo.com/api";
string tenantGuid = "00000000-0000-0000-0000-000000000000";

Step 2: Authenticate

You need to authenticate for most API calls. You can learn more on the API authentication reference. Use the /token endpoint to receive your bearer token.

Interact uses an OAuth 2.0 password-bearer authentication mechanism to acquire an access_token, which gives you access to perform actions using the API endpoints.

Important: The password-bearer authentication requires a username and password. It may be tempting to use a personal account, but this can break the connection if the user is ever deactivated, for example if they leave the company. Set up a dedicated user account within Interact that is only used for API connectivity, akin to a service account.

string token = ""; // Replace with the token from /token response

Step 3: Generate dynamic content

The content can be generated dynamically by an application, script, service or anything capable of creating HTML. HTML content is the heart of Interact pages and is the key component of dynamic page updates. The Page Composer API currently supports HTML only.

In the example below, we create an alert bar (a div) that writes out the current date and time. You can replace this with complex content, including combinations of HTML, CSS and JavaScript. Full React.js apps have been embedded in these uploads.

<div class="alert alert-info">Last Sync: {DateTime.Now}</div>

Step 4: Update the content

Once the content has been generated, push it to the Page Composer API with a PUT request to /api/page/{pageId}/composer — see the Page endpoint reference.

Note: Full endpoint details live in the API Reference.

Boilerplate

Combining all the steps above:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using RestSharp;

namespace PageComposerSync
{
    static class Program
    {
        static void Main()
        {
            // Required for API
            string apiDomain = "https://us-lb-api-01.interactgo.com/api";
            string tenantGuid = "00000000-0000-0000-0000-000000000000";
            string token = ""; // Replace with the token from /token response

            // Destination Page ID for syncing
            int pageId = 2000;

            // Create RestClient
            var restClient = new RestClient(apiDomain);

            // Create Page Update Request
            var request = new RestRequest($"/page/{pageId}/composer", Method.PUT);
            request.AddHeader("X-Tenant", tenantGuid);
            request.AddHeader("Authorization", $"Bearer {token}");
            request.AddHeader("Content-Type", "application/json");

            // Add request content - Page Composer PUT Schema (https://developer.interactsoftware.com/reference/pageidcomposer-1)
            var requestContent = new PageUpdateRequest();

            /// Transition
            requestContent.Transition = new Transition
            {
                State = "published",
                Message = DateTime.Now.ToString()
            };

            /// Page details - Tip: Use the Page Composer GET Endpoint to find all required meta information
            requestContent.Page = new Page()
            {
                ContentType = "html",
                TopSectionIds = new List<int>() { 3141 }, // Required
                AuthorId = 2, // Required
                PublishAsId = null,
                AssetId = 1999, // Required
                Title = "Sync Page", // Required
                Summary = $"Sync Page Summary", // Required
                Content = new Content()
                {
                    Html = $@"<div class=""alert alert-info"">Last Sync: {DateTime.Now}</div>" // Dynamic content here
                },
                CategoryIds = new List<int>() { 3145 }, // Required
                Features = new Features
                {
                    DefaultToFullWidth = false,
                    AllowComments = false,
                    IsKeyPage = false,
                    Recommends = new Recommends
                    {
                        MaxContentAge = null,
                        Show = false
                    }
                },
                PubStartDate = DateTime.Today, // Required
                PubEndDate = DateTime.Today.AddDays(7), // Required
                ReviewDate = DateTime.Today.AddDays(7), // Required
                TagIds = new List<object>() { },
                Keywords = new List<object>() { }
            };

            // Convert our page to JSON payload
            request.AddJsonBody(requestContent);

            // Execute the request
            var response = restClient.Execute(request);
            // response.Content ->
            /*
                {
                    "ContentId": 1234,
                    "VersionId": 1235,
                    "Acknowledged": true
                }
            */ 
        }
    }

    public class Transition
    {
        public string State { get; set; }
        public string Message { get; set; }
    }

    public class Content
    {
        public string Html { get; set; }
    }

    public class Recommends
    {
        public bool Show { get; set; }
        public object MaxContentAge { get; set; }
    }

    public class Features
    {
        public bool DefaultToFullWidth { get; set; }
        public bool AllowComments { get; set; }
        public bool IsKeyPage { get; set; }
        public Recommends Recommends { get; set; }
    }

    public class Page
    {
        public string ContentType { get; set; }
        public List<int> TopSectionIds { get; set; }
        public int AuthorId { get; set; }
        public object PublishAsId { get; set; }
        public int AssetId { get; set; }
        public string Title { get; set; }
        public string Summary { get; set; }
        public Content Content { get; set; }
        public List<int> CategoryIds { get; set; }
        public Features Features { get; set; }
        public DateTime PubStartDate { get; set; }
        public DateTime PubEndDate { get; set; }
        public DateTime ReviewDate { get; set; }
        public List<object> TagIds { get; set; }
        public List<object> Keywords { get; set; }
    }

    public class PageUpdateRequest
    {
        public Transition Transition { get; set; }
        public Page Page { get; set; }
    }
}

This was built with .NET Core 3.1, RestSharp 106.10.1 and Newtonsoft.Json 12.0.3.

Styling and CSS

You can include styling and CSS inline with style tags:

<style>
  h1 {color:red;}
  p {color:blue;}
</style>
<h1>Hello World!</h1>
<p>This is my dynamic content</p>

You can include inline styles:

<table>
  <tr style="font-weight: bold">
    <th>Row</th>
    <th>Name</th>
  </tr>
</table>

Tip: You can store the presentation and styling layer globally in the Custom CSS settings in Interact. Add classes to your HTML elements to reference the globally declared styles.

Custom CSS

.table {
  background-color: transparent;
  margin: 0.5em;
}

.header-row {
  font-weight: bold;
  color: darkgrey;
}

HTML upload

<table class="table">
  <tr class="header-row">
    <th>Row</th>
    <th>Name</th>
  </tr>
</table>

Automation

You can extend the boilerplate to fit your requirements and use a cronjob to run it on a schedule that suits your data. Your page is then updated dynamically and visible within your intranet.

Section: Customise & extend