Integration API / SDKs

The Skylight Integration API provides the ability to connect your Skylight applications to external systems. The APIs are offered as SDKs and are currently available for C#.

The SDKs are wrappers around APIs generated using OpenAPI Generator that provides functionality for querying information about applications and sessions, as well as event handling for session events.

The SDK takes care of fundamental aspects of Skylight integration code development that would otherwise be repeated between implementations, including:

  • Authenticating with Skylight

  • Refreshing access tokens when necessary

  • Subscribing to MQTT topics

  • Reconnecting to the MQTT broker when necessary

  • Providing models for Skylight applications and sessions

While the syntax may differ between the various languages, the concepts and provided methods of the different SDKs strive to be as similar as possible.

Getting Started

C#
C#

To use the C# SDK in your code, follow these steps:

  1. Ensure that .NET Core 3.1 is installed on your machine.

    • dotnet --version should return 3.1.301 or higher

    • dotnet nuget --version should return 5.6.0.5 or higher

  2. Scaffold out your project: dotnet new console -n myService cd myService

  3. Connect to the NuGet feed: https://pkgs.dev.azure.com/UpskillSDK/skylight-sdk/_packaging/release/nuget/v3/index.json -n skylightSdkRelease

    • For Visual Studio, use the NuGet package manager to connect to this feed.

    • For Visual Studio Code or other IDEs, connect to this feed by adding this feed in the nuget.config file, or by using the command: dotnet nuget add source https://pkgs.dev.azure.com/UpskillSDK/skylight-sdk/_packaging/release/nuget/v3/index.json -n skylightSdkRelease

  4. Install the Skylight SDK NuGet package:

    • For Visual Studio, use the NuGet package manager to install the latest version from this feed.

    • For Visual Studio Code or other IDEs, install the package by running dotnet add package Skylight.Sdk.

SDK Reference

The reference provides documentation on the SDK methods, events, and objects:

Example Code

C#
C#

The following snippet showcases the self-contained main .cs file of a project that uses the C# SDK.

using System;
using System.IO;
using System.Timers;
using System.Dynamic;
using System.Configuration;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using Skylight.Model;
using Skylight.Sdk;
using Newtonsoft.Json.Linq;
namespace SkylightSample
{
class Program : ISessionEventListener
{
// We'll store an instance of our Skylight.Sdk.Manager
static Manager _skyManager;
// These variables are used to store credentials and application information in config files. In a production setting, these should likely be stored/read as environment variables
static NameValueCollection _credentialsConfig, _applicationConfig;
// This is our main entry point
static async Task Main(string[] args)
{
// Retrieve our credentials and application configuration
SetupAppConfig();
// Create our manager
_skyManager = new Manager(new Program());
// Configure our credentials using one of three methods:
_skyManager.SetCredentials(_credentialsConfig["Username"], _credentialsConfig["Password"], _credentialsConfig["Realm"], _credentialsConfig["ApiUrl"], _credentialsConfig["MqttUrl"]);
// Configure manager after instantiation, here. Right now, this just sets the verbosity of the SDK.
_skyManager.SetVerbosity(Logger.Verbosity.Verbose);
// Connect our manager, which will connect us to Skylight APIs and MQTT.
await _skyManager.Connect();
// Run our various application and session method examples
//await RunApplicationExamples();
await RunSessionExamples();
//This keeps our program alive. Note that anything after this line will NOT get called. If we wish to use user input as our method of keeping the program alive, we should replace this line.
_skyManager.KeepAlive();
}
// This retrieves our credentials/application configuration -- in a product setting, this should likely read from environment variables
static void SetupAppConfig() {
//Open config
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//Update appconfig file path
config.AppSettings.File = Path.Join("config", "App.config");
//Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
//Force a reload in memory of the changed section.
ConfigurationManager.RefreshSection("applicationConfig");
ConfigurationManager.RefreshSection("credentialsConfig");
_credentialsConfig = ConfigurationManager.GetSection("credentialsConfig") as NameValueCollection;
_applicationConfig = ConfigurationManager.GetSection("applicationConfig") as NameValueCollection;
}
/*
Application and Session Method Examples
*/
static async Task RunApplicationExamples()
{
// Get Applications
Console.WriteLine("Get Applications");
var applications = await _skyManager.GetApplications();
foreach (var applicationFromList in applications)
{
Console.WriteLine(applicationFromList);
}
// Get Application
Console.WriteLine("Get Application");
var application = await _skyManager.GetApplication(_applicationConfig["Id"]);
Console.WriteLine(application);
// Get Application Roles
Console.WriteLine("Get Application Roles");
var applicationRoles = await _skyManager.GetApplicationRoles(_applicationConfig["Id"]);
foreach (var applicationRole in applicationRoles)
{
Console.WriteLine(applicationRole);
}
}
static async Task RunSessionExamples()
{
// Get Sessions
Console.WriteLine("Get Sessions");
var sessions = await _skyManager.GetSessions(_applicationConfig["Id"]);
foreach (var sessionFromApplication in sessions) {
Console.WriteLine(sessionFromApplication);
}
// Create Session
Console.WriteLine("Create Session");
var newSessionProperties = new Dictionary<string, string>();
newSessionProperties["customKey"] = "customValue";
var newSession = await _skyManager.CreateSession(_applicationConfig["Id"], "New Session", "This is a new session.", newSessionProperties);
Console.WriteLine(newSession);
// Patch Session
Console.WriteLine("Patch Session");
var sessionPatch = new SessionPatchRequest()
{
Name = "Patched Session",
Description = "This session has been patched."
};
await _skyManager.PatchSession(_applicationConfig["Id"], newSession.SessionId, sessionPatch);
// Get Session
Console.WriteLine("Get Session");
var patchedSession = await _skyManager.GetSession(_applicationConfig["Id"], newSession.SessionId);
Console.WriteLine(patchedSession);
// Update Session Name
Console.WriteLine("Update Session Name");
await _skyManager.UpdateSessionName(_applicationConfig["Id"], newSession.SessionId, "Latest Session");
// Update Session Description
Console.WriteLine("Update Session Description");
await _skyManager.UpdateSessionDescription(_applicationConfig["Id"], newSession.SessionId, "This session description has been updated.");
// Update Session Properties
Console.WriteLine("Update Session Properties");
var updatedSessionProperties = new Dictionary<string, string>();
updatedSessionProperties["anotherCustomKey"] = "anotherCustomValue";
await _skyManager.UpdateSessionProperties(_applicationConfig["Id"], newSession.SessionId, updatedSessionProperties);
// Patch Session Data
Console.WriteLine("Patch Session Data");
await _skyManager.PatchSessionData(_applicationConfig["Id"], newSession.SessionId, new Worklist("Worklist 0"));
// Get Session Data
Console.WriteLine("Get Session Data");
var worklist = await _skyManager.GetSessionData<Worklist>(_applicationConfig["Id"], newSession.SessionId);
Console.WriteLine(worklist);
// Add Session Participant
Console.WriteLine("Add Participant");
//await _skyManager.AddParticipant(_applicationConfig["Id"], newSession.SessionId, "dummy-group-id", SessionParticipantPostRequest.TypeEnum.Group);
// Close Session
Console.WriteLine("Close Session");
await _skyManager.CloseSession(_applicationConfig["Id"], newSession.SessionId);
}
/*
Event Listener Examples
*/
async Task ISessionEventListener.OnSessionCreated(SessionEventBase sessionEvent)
{
Console.WriteLine("Session created");
Console.WriteLine(sessionEvent.ToString());
var properties = sessionEvent.Session.Properties;
Console.WriteLine(properties.ToString());
foreach (KeyValuePair<string, string> kvp in properties)
{
Console.WriteLine("{"+kvp.Key + "," + kvp.Value+"}");
}
}
async Task ISessionEventListener.OnSessionPropertiesUpdated(SessionEventBase sessionEvent)
{
Console.WriteLine("Session properties updated: " + sessionEvent.SessionId);
Console.WriteLine(sessionEvent.ToString());
var properties = sessionEvent.Session.Properties;
Console.WriteLine(properties.ToString());
foreach (KeyValuePair<string, string> kvp in properties)
{
Console.WriteLine("{"+kvp.Key + "," + kvp.Value+"}");
}
}
async Task ISessionEventListener.OnSessionUpdated(SessionEventBase sessionEvent)
{
Console.WriteLine("Session updated");
Console.WriteLine(sessionEvent.ToString());
}
async Task ISessionEventListener.OnSessionClosed(SessionEventBase sessionEvent)
{
Console.WriteLine("Session closed: " + sessionEvent.SessionId);
Console.WriteLine(sessionEvent.ToString());
}
async Task ISessionEventListener.OnSessionDataUpdated(SessionEventBase sessionEvent)
{
Console.WriteLine("Session data updated");
Console.WriteLine(sessionEvent.ToString());
JObject data = sessionEvent.Data as JObject;
Console.WriteLine(data.ToString());
// Example of converting the JSON Object to our own class that we passed into the session data update
try {
Worklist worklist = data.ToObject<Worklist>();
Console.WriteLine("Our session data as a worklist object:");
Console.WriteLine(worklist.title);
} catch (Exception e) {
Console.Error.WriteLine(e);
}
}
async Task ISessionEventListener.OnSessionEventCreated(SessionEventBase sessionEvent)
{
Console.WriteLine("Session event created");
Console.WriteLine(sessionEvent.ToString());
}
}
// This is an example of an object used to represent a worklist
class Worklist {
public string title;
public List<Step> steps;
public Worklist(string title) {
this.title = title;
}
}
// This is an example of an object used to represent a step in worklist
class Step {
public string name;
public Step otherStep;
public void Hello() {
Console.WriteLine("Hi this is a step");
}
}
}