Notifications to MS Teams

Perhaps I am late to the ball game, but I just implemented a solution to send alerts from Epicor to Teams (as opposed to email). Gamechanger.

GIST:

The article speaks to PS but I just used REST.

I vote for @hkeric.wci to do a proper Linked In article on it.

8 Likes

I know @jgehling was able to implement nicely this via webhooks and BPMs too

2 Likes

Thanks @Aaron_Moreng !

Here is some boiler plate code to put in your server side BPM (RestSharp & Newtonsoft JSON library’s are dependencies)


Action<ResponseStatus, string, string> notifyTeams = (status, message, title) =>
  {
    var client = new RestClient(webhookURL);
    
    int responseStatusCodeTeams = 0;
    string themeColor = "0072C6";
  
    if(status == ResponseStatus.Completed)
    {
      themeColor = "0008FF";
    }
    else if (status == ResponseStatus.Error)
    {
      themeColor = "8B0000";
    }
    else if (responseStatusCode < 200 || responseStatusCode > 400)
    {
      themeColor = "8B0000";
    }
    
    var data = new
        {
          context = "https://schema.org/extensions",
          type = "MessageCard",
          themeColor = themeColor,
          title = title,
          text = message
        };
    
    var content = JsonConvert.SerializeObject(data);
    
    //Begin Create REST Request
    var request = new RestRequest(Method.POST);
    request.AddHeader("Accept", "application/json");
    request.AddJsonBody(content);
   
    var response = client.Execute(request);
    responseStatusCodeTeams = (int)response.StatusCode;
    //End Execute REST Request
  };
1 Like

Moving from email (point-to-point communication) to a group notification is a huge improvement. The game changer? Actionable notifications:

https://adaptivecards.io/samples/ExpenseReport.html

1 Like

Notice how Theme changes color @ERPSysAdmin

Quick Dirty Example

// Add NewtonSoft and RestSharp Assemblies
Action < ResponseStatus, string, string > notifyTeams = (status, message, title) => {
  var client = new RestClient("https://yourco.webhook.office.com/webhookb2/b62d6918-1152-47d6-9276-780e37d4a21a@99182fcd-14a7-436d-921a-2013548939cd/IncomingWebhook/8bbfe7bc4c54a54bfe8d1cd9f7805a6/2-ea25-40bb-a7f1-f15e55c94a87");

  int responseStatusCodeTeams = 0;
  string themeColor = "0072C6";

  if (status == ResponseStatus.Completed) {
    themeColor = "0008FF";
  } else if (status == ResponseStatus.Error) {
    themeColor = "8B0000";
  }

  var data = new {
    context = "https://schema.org/extensions",
      type = "MessageCard",
      summary = "Incoming Alert Message!",
      themeColor = themeColor,
      // title = title,
      //text = message,
      markdown = true,
      sections = new [] {
        new {
          activityTitle = "Part *HASOTEST* has been updated!",
            activitySubtitle = $ "Company {Session.CompanyID} - User: RCKNRL",
            activityImage = "https://www.pngmart.com/files/11/Rickrolling-PNG-Transparent-Image.png",
            facts = new [] {
              new {
                name = "Description", value = "Haso was here -> Hello Rick Rollers"
              },
              new {
                name = "UOM", value = "EA -> SH"
              }
            }
        }
      }
  };

  var content = JsonConvert.SerializeObject(data);

  //Begin Create REST Request
  var request = new RestRequest(Method.POST);
  request.AddHeader("Accept", "application/json");
  request.AddJsonBody(content);

  var response = client.Execute(request);
  responseStatusCodeTeams = (int) response.StatusCode;
  //End Execute REST Request
};

notifyTeams(ResponseStatus.Error, "Haso has updated ABCCode", Session.CompanyName);
4 Likes

That is so cool!

Can you send a Teams message to a specific person or does it have to go to a channel?

Brett

The connector approach is specific to a teams channel, as that’s where the webhook connector is configured to. I am not 100 percent sure if they have built out their Graph API to send messages in Teams yet, but you could use that approach too (not a connector, but plain old rest API to Microsoft Graph)

Graph Explorer - Microsoft Graph

Looks like you create a one-on-one chat with the graph.

Show me sparkles and unicorns and rainbows and kittens (Oh My!) and THEN I’ll be impressed…LOL :wink:

image

That’s Awesome @hkeric.wci! :slight_smile:

5 Likes

May I push back on this a little bit? What is the business case that one would want a notification to go to a single person?

When, not if, a person leaves a role or the organization then there is a loss of communication from that point forward. The history of that notification is completely lost on the next person filling the role. Sure, we can give access to the mailbox but what if the person had multiple roles and other roles were sending more sensitive information? What if the original receiver permanently deleted the notice? What if the receiver is temporarily out of the office for planned or unplanned reasons?

I would prefer a single-person team over sending notices to a single person. Just my .02 EUR.

Cheers,

Mark W.

6 Likes

Somehow I expected some push back on that one :slight_smile:

We have several email notifications going to job planners, buyers etc when triggers fire. This at least alerts them to issues but does nothing for anyone in the future that might need that info as you rightly point out. We are about to implement Collaborate which will hopefully allow us to send messages to the job. This will leave a record of the issue on the job for future which is good. I am thinking an improvement would be for Collaborate to also send a Teams message to the planner because they are most likely not at their desk.

Just my AUD$ 0.03 = 0.02 EUR :grinning:

Brett

I guess this has been one of my concerns with Social and now Collaborate: if one already has a collaboration tool (Teams/Slack/…), why create another? :man_shrugging:

And if the planner is on holiday? How does the person covering the planner those days get the message? :thinking:

AUD 0.03 = CAD 0.04 (Detroit is a border town, so we get some loony currency at times! :rofl: ) Sorry! I had you on the wrong continent for some reason!!!

1 Like

I was able to get through the Microsoft setup and example using PostMan.
Does anyone have any code examples to do this from a UI customization?

This post from @mng may help:

Custom Library for sending REST calls out of Epicor - Code Review / Sharing

Thank you for that. I’m getting stuck at the very beginning.
I copied RestSharp.dll to my client folder, added the assembly reference and I see “extern alias RestSharp;” near the top of the script window.
I add “using RestSharp;” and Test Code.
I get the following error:

Error: CS0576 - line 59 (59) - Namespace ‘<global namespace>’ contains a definition conflicting with alias ‘RestSharp’

In your customization, go to:

image

Click Add Custom Reference and browse to the RESTSharp DLL.

image

Wait. RestSharp might be included in 10.2.600… Try taking out the reference to the DLL.

It is not included in 10.2.600. I downloaded the DLL and copied to my client folder. I then added it using the assembly reference manager.

We are using RestSharp in BPMs but in this case, I want to send the messages to Teams from a UI customization. I copied the RestSharp dll from the external folder on the server assuming that this version is the one that I should be using.

Any pointers on what I am missing?

Another method for this; write a record to a UD table from your UI customization with the data you want to send. Listen to the UD table additions and consume the record server side, using your existing RestSharp server assembly to call the Graph API. Update your UD table record with a success/fail response based on the API response and have a call history and ability to re-try failed ones.