
Microsoft 365 Send
CertifiedSend an Adaptive Card to a Teams channel
Microsoft 365 Send
Send an Adaptive Card to a Teams channel
Posts a Microsoft Adaptive Card to a Teams channel via the Microsoft Graph API. Unlike teams.TeamsIncomingWebhook, this task targets any channel by ID and returns the created message ID.
Sending a channel message requires DELEGATED (acting-as-user) authentication: set username and password so the task authenticates as a real user. App-only clientSecret (or pemCertificate) credentials are rejected by Microsoft Graph with an HTTP 403, since channel messages cannot be sent with application permissions alone.
type: io.kestra.plugin.microsoft365.teams.adaptivecards.SendExamples
Send an Adaptive Card to a Teams channel
id: send_adaptive_card_to_channel
namespace: company.team
tasks:
- id: send_card
type: io.kestra.plugin.microsoft365.teams.adaptivecards.Send
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
teamId: "{{ secret('TEAMS_TEAM_ID') }}"
channelId: "{{ secret('TEAMS_CHANNEL_ID') }}"
card: |
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"size": "Large",
"weight": "Bolder",
"text": "Kestra Pipeline Report"
},
{
"type": "FactSet",
"facts": [
{ "title": "Flow", "value": "{{ flow.id }}" },
{ "title": "Status", "value": "{{ execution.state.current }}" },
{ "title": "Execution ID", "value": "{{ execution.id }}" }
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "View in Kestra",
"url": "{{ kestra.url }}/ui/executions/{{ flow.namespace }}/{{ flow.id }}/{{ execution.id }}"
}
]
}
Send a card on flow failure
id: monitored_pipeline
namespace: company.team
tasks:
- id: process
type: io.kestra.plugin.scripts.shell.Commands
commands:
- ./run_pipeline.sh
errors:
- id: alert_team
type: io.kestra.plugin.microsoft365.teams.adaptivecards.Send
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
teamId: "{{ secret('TEAMS_TEAM_ID') }}"
channelId: "{{ secret('TEAMS_CHANNEL_ID') }}"
card: |
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"size": "Large",
"weight": "Bolder",
"color": "Attention",
"text": "Pipeline Failed"
},
{
"type": "TextBlock",
"text": "Flow `{{ flow.id }}` failed at {{ execution.state.startDate }}.",
"wrap": true
}
]
}
Send an Adaptive Card to a Teams channel using delegated (username/password) authentication
id: send_adaptive_card_delegated
namespace: company.team
tasks:
- id: send_card
type: io.kestra.plugin.microsoft365.teams.adaptivecards.Send
tenantId: "{{ secret('AZURE_TENANT_ID') }}"
clientId: "{{ secret('AZURE_CLIENT_ID') }}"
username: "{{ secret('AZURE_USERNAME') }}"
password: "{{ secret('AZURE_PASSWORD') }}"
teamId: "{{ secret('TEAMS_TEAM_ID') }}"
channelId: "{{ secret('TEAMS_CHANNEL_ID') }}"
card: |
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"size": "Large",
"weight": "Bolder",
"text": "Kestra Pipeline Report"
},
{
"type": "FactSet",
"facts": [
{ "title": "Flow", "value": "{{ flow.id }}" },
{ "title": "Status", "value": "{{ execution.state.current }}" }
]
}
]
}
Properties
card *Requiredstring
Adaptive Card payload
The Adaptive Card JSON payload, rendered as a Pebble template before being sent. See https://adaptivecards.io/explorer/ for the schema reference.
channelId *Requiredstring
Channel ID
The Teams channel identifier to post the card into
teamId *Requiredstring
Team ID
The Microsoft Teams team identifier that owns the target channel
clientId string
Client ID
Client ID of the Azure service principal. If you don't have a service principal, refer to create a service principal with Azure CLI.
clientSecret string
Client Secret
Service principal client secret. Use this for Client Secret authentication. Provide clientId, tenantId, and clientSecret. Either clientSecret OR pemCertificate must be provided, not both.
password string
Password
Password of the delegated user, used together with username for Resource Owner Password Credentials (ROPC) authentication. Requires the Azure AD app registration to have "Allow public client flows" enabled and the relevant delegated Graph permission granted (e.g. ChannelMessage.Send or Chat.ReadWrite).
pemCertificate string
PEM Certificate
Alternative authentication method using certificate-based authentication.
Use this for Client Certificate authentication. Provide clientId, tenantId, and pemCertificate.
Either clientSecret OR pemCertificate must be provided, not both.
pluginDefaultsRef Non-dynamicstring
Reference (ref) of the pluginDefaults to apply to this task.
tenantId string
Tenant ID
username string
Username
Username of the delegated user to authenticate as (Resource Owner Password Credentials flow). Set this together with password for delegated (acting-as-user) authentication instead of app-only clientSecret/pemCertificate credentials. This is required for operations Microsoft Graph rejects under app-only auth, such as sending Teams channel or chat messages. Requires the Azure AD app registration to have "Allow public client flows" enabled and the relevant delegated Graph permission granted (e.g. ChannelMessage.Send or Chat.ReadWrite).
Outputs
createdDateTime string
Created date time
ISO-8601 timestamp of when Microsoft Graph created the message
messageId string
Message ID
Identifier of the sent chat message, usable to reply or look it up later