MS Teams Channel
Norq compiles Teams templates to Adaptive Card v1.5 JSON. Adaptive Cards (Microsoft's rich message format for Teams) are the standard format for rich messages in Microsoft Teams.
Pipeline: Markdown -> AST (parse tree) -> Adaptive Card JSON
Template files
msteams.md-- Markdown modemsteams.json-- Native JSON mode (for inputs, toggles, custom layouts)
Frontmatter
---
enabled: true
---| Field | Required | Description |
|---|---|---|
enabled |
No | true (default) or false. |
Directive compilation
| Directive | Teams output |
|---|---|
:::header |
TextBlock with ExtraLarge size + Bolder weight |
:::footer |
TextBlock with isSubtle=true, size=Small |
:::action |
Action.OpenUrl entries in the card actions array |
:::callout |
Container with style=accent |
:::hero |
Image element with size=Stretch |
:::fields |
FactSet with title/value facts |
:::media |
Image element; altText from alt attribute |
:::columns |
ColumnSet with Column elements (width=stretch) |
:::list |
TextBlock with list-formatted text |
:::raw |
Parsed JSON inserted as Adaptive Card element |
Example
::: header
Order Shipped
:::
Hey {{user.first_name}}, your order **#{{order.id}}** has shipped!
::: fields
Tracking ID: {{order.tracking_id}}
Delivery: {{order.delivery_date}}
:::
::: action
[Track Order]({{tracking_url}}){primary}
:::
::: footer
Order notification | {{company_name}}
:::Compiled output
The output is an Adaptive Card JSON structure:
{
"card": {
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Order Shipped",
"size": "ExtraLarge",
"weight": "Bolder"
},
{
"type": "TextBlock",
"text": "Hey Gaurav, your order **#ORD-123** has shipped!",
"wrap": true
},
{
"type": "FactSet",
"facts": [
{ "title": "Tracking ID", "value": "TRK-456" },
{ "title": "Delivery", "value": "Mar 30" }
]
},
{
"type": "TextBlock",
"text": "Order notification | Acme Corp",
"isSubtle": true,
"size": "Small"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "Track Order",
"url": "https://track.example.com/123"
}
]
}
}Native JSON mode
For Adaptive Card features beyond what directives cover (Input.Text, Input.Toggle, Action.Submit, ColumnSet with specific widths), use msteams.json:
{
"$norq": { "enabled": true },
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Rate your delivery",
"size": "Large",
"weight": "Bolder"
},
{
"type": "Input.ChoiceSet",
"id": "rating",
"label": "How was your experience?",
"choices": [
{ "title": "Excellent", "value": "5" },
{ "title": "Good", "value": "4" },
{ "title": "Average", "value": "3" }
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit Rating"
}
]
}Inline formatting
Adaptive Cards support a subset of Markdown:
| Markdown | Adaptive Card |
|---|---|
**bold** |
Rendered bold |
*italic* |
Rendered italic |
[text](url) |
Hyperlink |
- list item |
Bullet list |
1. list item |
Numbered list |
Best practices
- Adaptive Cards have a payload size limit -- keep cards focused
- Use
:::fieldsfor structured data (renders as FactSet, which looks great in Teams) - Use
:::rawwith Adaptive Card JSON for interactive elements (inputs, choices) - Test with
norq preview <name> --channel msteamsto validate the card structure - Action.OpenUrl is the most compatible action type across Teams clients