Notifications

Each pico, from the moment it is created, is a first-class Internet resource, exposing a rich API of events and queries. It maintains a boundary between its internal state and the outside world.

When something interesting happens inside the pico the owner/controller of the pico may want to be notified.

A previous post about sending email illustrated this for that notification method. In this post, we'll discuss sending a message into a Microsoft Teams channel. Similar techniques can be used so that our pico can notify other message systems.

Obtaining a webhook for Teams channel

Ultimately, the notification will be achieved through the use of a webhook. Given* a channel in Teams, it is a simple matter to ask for a URL that can be used to inject a message into the channel. Detailed instructions can be found in the Teams document, Creating Incoming Webhooks.

The webhook (as of this writing) has a fairly simple structure:

https://ORG.webhook.office.com/webhookb2/GUID1@GUID2/IncomingWebhook/GUID3

A subdomain identifies your Teams organization (shown here as ORG). Later there are three Globally Unique Identifiers (GUIDs) that will uniquely identify you and the channel.

Once you have your webhook in the copy buffer, paste it into a JSON string with this format:

{"webhook":"https://ORG.webhook.office.com/webhookb2/..."}

and save this somewhere locally. This author uses a file named "secrets.txt" for such purposes**.

Using the webhook to send a notification

In a moment, we'll show a ruleset that sends a notification. 

Installing a notification ruleset

First, here is how that ruleset will be installed in a pico where interesting things happen:


Writing a notification ruleset

Having identified an interesting event which will be raised in the pico, we write a new ruleset with a rule that reacts to that event by using the webhook to inject a message into the Teams channel.

ruleset teams.webhook.messaging {
  global {
    webhook = meta:rulesetConfig{"webhook"}
  }
  rule sendMessage {
    select when byname_notification status
      application re#(org.picostack.get_me_ribs)#
      subject re#(Cannon Has .+)#
      description re#(.+)#
      setting(app,subj,desc)
    http:post(webhook,json={"title":subj,"text":desc})
  }
}

The select when clause identifies the event domain and type, and selects only on a particular application and a matching subject by looking at the attributes of the event, and matching them against regular expressions.

Once the rule selects, it fires, and the action part of the rule does the work, using http:post to send a message through the webhook.

Origin of the interesting event

The previous post, Scheduling Events, talked about an application that raised an event every morning. The rule that selects each morning is repeated here from that post, for the reader's convenience:

rule checkEveryMorning {
    select when org_picostack_get_me_ribs it_is_morning
    pre {
      menu = time:now().get_lunch_menu()
      found_fav_food = menu.has_fav_food()
    }
    if found_fav_food then noop()
    fired {
      raise byname_notification event "status" attributes {
        "application": meta:rid,
	"subject": "Cannon Has " + found_fav_food,
	"description": "Found " + found_fav_food.lc() + " on the menu today!"
      }
    }
  }

The rule raises the byname_notification:status event if something interesting has happened. Compare the raise event statement in this rule with the select when clause of the rule in the new ruleset above.

What the notification looks like


The icon and the label "CannonFood" were selected when the incoming webhook was created. The reader should be able to identify the title and text of the message within a rectangular border.

Our pico is now able to notify us, in the world outside of itself, when something interesting happens inside of it.

Ruleset layering

The astute reader will notice that all we did to make our existing pico — with its pre-existing rulesets — begin to notify us of internal events, was to install a very small ruleset (just 13 lines of code).

This illustrates one of the advantages of using picos to create web applications. We can layer in additional rulesets so that the pico has additional functionality.

Notes

* for instructions on creating a private channel, see Create a standard or private channel in Teams

** then the question becomes, where to put that file for future reference? One convenient place is in a code repository. But then be sure you have a .gitignore file (like this one, for example) that contains the name of your secrets file, so that you won't accidentally make your secrets public.

No comments:

Post a Comment