We will be using MS Teams incoming webhook to POST ServiceNow Incidents assigned to a specific group into a MS Teams channel.
To make things simpler, we will create a .net core console app.
One advantage of a console app is it is very lightweight and you can take advantage of the scheduled task or job to configure the app to run at a specific time of the day.
Here are our main steps,
- Create console app in C#.
- Create necessary classes for messages.
- Create class for notification.
Let us get started...
Create console app in C#
- Start Visual Studio 2019 and Click on Create a new project
- Pick Console Application that can run on .NET Core using C#

- Configure your new project. Give it a good name.

- Pick your target framework. We will pick .net 5.0 for this example

We will start working on our classes. We will create classes for serialization/deserialization logic for the results coming back from ServiceNow API call. The de-serialized object will used for our adaptive card that will eventually be posted to a Microsoft Teams channel. This will all be in our Messages.cs file.
We will be using TableAPIs in ServiceNow, specifically incidents for this example. Basic authentication will be connecting to ServiceNow APIs. Please make sure you have an account with enough rights that you can use for this connectivity.
We will also create a Notification class with methods to retrieve ServiceNow incidents assigned to a specific group and then push the incidents as adaptive cards to a MS Teams channel. We will have this all in our Notify method which will be called from our entry point method (Main) in program.cs.
Please note:
I have made the following changes inside the entry point Main method in Program.cs file.
- Added logic to configure appsettings.json to store our configuration entries.
- Never store any critical or sensitive information exposed in configuration file. For this example, I have stored the configuration entries, including the bearer token required for ServiceNow authentication. It is best to encrypt and store any sensitive information in env files or use key vault services.
- /// <summary>
- /// setupConfiguration
- /// To enable appsettings.json configuration
- /// </summary>
- private static void SetupConfiguration()
- {
- var builder = new ConfigurationBuilder()
- .AddJsonFile($"appsettings.json", true, true);
- var config = builder.Build();
- _config = config;
- }
- Added logic in our entry point Main method to call into SetupConfiguration() method. Also used Task.Wait() call to wait for our async Notify call to complete execution. Please note that I am also passing in _config object to Notification class to read the configuration object from our Notification class.
- private static IConfigurationRoot _config;
- static void Main(string[] args)
- {
- SetupConfiguration();
- u
- Console.WriteLine("Hello! Here are the active incidents for our team.");
- Notification notification = new(_config);
- Task t = notification.Notify();
- t.Wait();
- }
Notification (Notification.cs):
- private readonly IConfigurationRoot _config;
- public Notification(IConfigurationRoot config)
- {
- _config = config;
- }
Create necessary classes for messages
We will add all our classes necessary for our deserialization and adaptive cards inside our Messages.cs file.
Messages.cs
- /// <summary>
- /// Teams Message for Adaptive Cards
- /// </summary>
- class TeamsMessage
- {
- [JsonProperty("type")]
- public string Type { get; set; }
- [JsonProperty("themeColor")]
- public string ThemeColor { get; set; }
- [JsonProperty("summary")]
- public string Summary { get; set; }
- [JsonProperty("sections")]
- public TeamsMessageSections[] Sections { get; set; }
- }
- /// <summary>
- /// Teams Message for Adaptive Cards
- /// </summary>
- public class TeamsMessageSections
- {
- [JsonProperty("activityTitle")]
- public string ActivityTitle { get; set; }
- [JsonProperty("activitySubtitle")]
- public string ActivitySubtitle { get; set; }
- [JsonProperty("activityImage")]
- public string ActivityImage { get; set; }
- [JsonProperty("markdown")]
- public bool Markdown { get; set; }
- }
- /// <summary>
- /// ServiceNow Table API Return Object Arrsy
- /// </summary>
- public class ServiceNowReturn
- {
- [JsonProperty("result")]
- public ServiceNowReturnMessage[] Result { get; set; }
- }
- /// <summary>
- /// ServiceNow Table API Return Object for Teams Adaptive Card
- /// </summary>
- public class ServiceNowReturnMessage
- {
- [JsonProperty("number")]
- public string Number { get; set; }
- [JsonProperty("u_best_contact_email")]
- public string ContactEmail { get; set; }
- [JsonProperty("sys_id")]
- public string SysID { get; set; }
- [JsonProperty("short_description")]
- public string ShortDescription { get; set; }
- [JsonProperty("description")]
- public string Description { get; set; }
- }


Join the conversation! Your thoughts help the community grow.