Auto-Route Issue by Label
On issue open/labeled, reads the issue's labels and routes notifications: 'bug' → dev Teams channel, 'security' → security channel, 'docs' → docs channel, unlabeled → triage.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow automatically watches a GitHub repository for newly opened issues, reads their labels, and posts a formatted notification to the appropriate Microsoft Teams channel based on label-driven routing rules. It keeps triage lean by surfacing bugs, security issues, and documentation gaps to the right specialist channels — and everything else goes to a generic triage channel so nothing is lost.
Use Case
Engineering teams often struggle with noisy GitHub notifications: the "everything feed" in Teams or email buries high-signal issues under low-priority chatter. This flow lets a GitHub admin wire up label-based triage once, then lets the responsible channels own their queues. Bug reports land in the dev channel. Security findings route to the security response team. Doc issues drop into the documentation channel. Unlabeled issues go to triage so someone can apply the right label and restart the routing.
The flow is ideal for teams that:
- Reduce noise in shared dev channels by routing issues to specialist channels.
- Ensure security-labeled issues always reach the security team first.
- Catch unlabeled issues in a dedicated triage channel rather than dropping them.
- Decouple routing rules from channel ownership — each team owns its queue.
Flow Architecture
When a new issue is opened
GitHub IssueOpenedPolls every 5 minutes; splitOn fans each new issue into its own run.
Init 7 routing variables
InitializeVariablePulls varRepoOwner, varRepoName, varTeamsGroupId, varBugChannelId, varSecurityChannelId, varDocsChannelId, varTriageChannelId from env vars.
Get Issue Labels
GitHub GetIssueLabelsFetches all labels currently applied to the triggering issue by number.
Select Label Names
Data Operations SelectProjects the labels array to a flat array of label name strings for easy contains() checks.
Compose Route Key
ComposeNested if() expression that picks one of security / bug / docs / triage in priority order.
Switch On Route
SwitchRoutes on the computed route key with three explicit cases plus a default branch.
- security → Post to Security Channel — Teams PostMessageToConversation with a 🛡️ prefix and a direct link.
- bug → Post to Bug Channel — Teams PostMessageToConversation with a 🐛 prefix and a direct link.
- docs → Post to Docs Channel — Teams PostMessageToConversation with a 📝 prefix and a direct link.
Teams PostMessageToConversation into the triage channel for unlabeled issues.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GitHubRepoOwner | String | — | GitHub user or organization that owns the repo being watched. |
| flowlibs_GitHubRepoName | String | — | Name of the GitHub repository. |
| flowlibs_TeamsGroupId | String | — | Microsoft Teams team ID hosting the routing channels. |
| flowlibs_TeamsBugChannelId | String | — | Teams channel ID for bug notifications (issues labeled `bug`). |
| flowlibs_TeamsSecurityChannelId | String | — | Teams channel ID for security notifications. Highest routing priority. |
| flowlibs_TeamsDocsChannelId | String | — | Teams channel ID for documentation notifications (issues labeled `docs`). |
| flowlibs_TeamsTriageChannelId | String | — | Fallback channel for unlabeled issues and any labels not matching the three routing buckets. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| GitHub | shared_github | IssueOpened (trigger) GetIssueLabels |
| Teams | shared_teams | PostMessageToConversation (posts routed messages into four Teams channels) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Add or rename routing labels
- Edit the Compose Route Key expression to match your label vocabulary (e.g. defect instead of bug).
- Add new routing buckets
- Duplicate an existing case in the Switch and add a new flowlibs_Teams<Name>ChannelId env var to map a fresh label to its own channel.
- Adjust priority ordering
- Re-order the nested if() calls in Compose Route Key if your team's priority differs from security → bug → docs.
- Change polling interval
- Edit the trigger recurrence block. Faster polling gives near-real-time routing but increases API consumption.
- Replace message templates
- The Teams HTML body strings inside each Switch case are independent — give each channel its own style without affecting others.
- Fan-out instead of route
- Replace the Switch with parallel Condition branches if an issue labeled both bug and security should notify both channels.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Pull issue number from trigger
Used to call GetIssueLabels for the triggering issue.
EXPR.02Project labels to names array
Used in the Select map.
EXPR.03Compose route key (priority order)
Picks the highest-priority matching label or falls back to triage.
EXPR.04Build direct GitHub issue URL
Used inside each Teams message body for a one-click jump.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.