Documentationbreadcrumb arrow Grafana Cloudbreadcrumb arrow Platformbreadcrumb arrow Workflowsbreadcrumb arrow Referencebreadcrumb arrow Blueprintsbreadcrumb arrow Announce on-call changes in Microsoft Teams
Public preview Grafana Cloud
Last reviewed: November 9, 2026

Announce on-call changes in Microsoft Teams

Note

Grafana Workflows is currently in public preview. Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available.

Announce on-call changes in a Microsoft Teams channel so everyone knows who to contact.

This Grafana Workflows blueprint is in the On-call category of the Blueprints library.

Before you begin

To use this blueprint, you need:

Steps

Steps run in order from first to last. A step inside a switch branch runs only when Workflows chooses that branch.

StepIDTypeDescription
Only this scheduleonly-this-schedulefilterStops the run unless the change happened on your schedule. Put the exact IRM schedule name between the quotes.
Build the announcement cardbuild-cardcode.executeBuilds an Adaptive Card that lists who is now on call and who joined or left. Edit the card layout if you like.
Post to Teamspost-cardmsteams.message.postPosts the announcement. Pick the Teams team and channel where people look for on-call contacts.

For the inputs and outputs of each step type, refer to Step and trigger types reference.

Before you turn on the workflow, customize any steps that need input from you, such as a channel ID or a schedule name. Each step’s description says what to set.

Workflow definition

Save this definition as a YAML file to create the workflow with gcx, the Workflows API, or Terraform, or give it to a coding agent as an example. Replace FOLDER_UID with the UID of the folder for the workflow. Blueprints start disabled, so finish customizing the steps before you set enabled to true. For details, refer to Manage workflows as code.

YAML
apiVersion: workflows.ext.grafana.app/v1alpha1
kind: Definition
metadata:
  name: announce-on-call-changes-teams
  annotations:
    grafana.app/folder: <FOLDER_UID>
spec:
  name: Announce on-call changes in Microsoft Teams
  enabled: false
  startWhen:
    matchingRules:
      - eventNameRegex: 'grafana_irm_app\.schedule\.updated'
    schedules: []
  steps:
    - id: only-this-schedule
      type: filter
      name: Only this schedule
      description: Stops the run unless the change happened on your schedule. Put the exact IRM schedule name between the quotes.
      inputs:
        condition: "inputs.data.schedule.name == ''"
    - id: build-card
      type: code.execute
      name: Build the announcement card
      description: Builds an Adaptive Card that lists who is now on call and who joined or left. Edit the card layout if you like.
      inputs:
        language: 'python'
        code: |
          import json

          data = context["inputs"]["data"]

          def names(users):
              return ", ".join(u.get("username") or u.get("email") or "unknown" for u in users) or "nobody"

          card = {
              "type": "AdaptiveCard",
              "version": "1.4",
              "body": [
                  {
                      "type": "TextBlock",
                      "text": f"On-call update: {data['schedule']['name']}",
                      "size": "Medium",
                      "weight": "Bolder",
                      "wrap": True,
                  },
                  {
                      "type": "FactSet",
                      "facts": [
                          {"title": "Now on call", "value": names(data.get("currentOnCall", []))},
                          {"title": "Joined", "value": names(data.get("usersAdded", []))},
                          {"title": "Left", "value": names(data.get("usersRemoved", []))},
                      ],
                  },
              ],
          }
          print(json.dumps(card))
    - id: post-card
      type: msteams.message.post
      name: Post to Teams
      description: Posts the announcement. Pick the Teams team and channel where people look for on-call contacts.
      inputs:
        teamID: ''
        channelID: ''
        messageText: 'On-call update: ${inputs.data.schedule.name}'
        adaptiveCard: "${steps['build-card'].outputs.stdout}"

How it works

This section explains when the workflow runs and how its steps work together.

When it runs

This blueprint starts on the grafana_irm_app.schedule.updated event.

How the steps fit together

These notes cover how the steps connect and which Workflows behaviors the blueprint relies on.

  • Triggers on grafana_irm_app.schedule.updated, which fires when on-call users change.
  • A filter step limits it to one schedule, because the event fires for every schedule in the stack.
  • A Python code.execute step reads currentOnCall, usersAdded, and usersRemoved from context[“inputs”][“data”] and builds the Adaptive Card.
  • Python is used here because joining lists of names is easy in Python and awkward in CEL, which has no string join.
  • The script prints the card as JSON, and stdout is passed straight to the adaptiveCard input of msteams.message.post.
  • Customize the schedule name, the Teams team and channel, and the card layout.

Next steps