Send FyneDesk notifications to Microsoft Teams

Get a message in your Teams channel every time a ticket is created, commented on, or changes status. FyneDesk sends the event to a webhook, and a short Power Automate flow turns it into a Teams message. Follow the steps below in order — it takes about ten minutes.

Tested it and saw "sent successfully" but nothing in Teams? That's expected — and you're almost done. The "success" only means Microsoft received the data; it doesn't post anything on its own. Add the one posting action in Part 3 below and messages will start appearing.

How it works

FyneDesk sends each event (new ticket, new comment, and so on) as a small JSON data packet to the URL you provide. Microsoft Teams doesn't display that packet on its own — your Power Automate flow has to take the data and post it as a message.

This is why a test can say "sent successfully" while nothing shows up in Teams: Power Automate replies 202 Accepted the instant it receives a request, so "success" only means Microsoft received the data. It says nothing about whether a message was posted. Once you add the posting step in Part 3, messages will appear.

Before you start

  • A Microsoft Teams team and channel where you want the notifications, and a Power Automate account with a licence that can post to Teams.
  • Admin access to FyneDesk webhooks, under Admin Settings → Advanced → Webhooks (also reachable via Settings → Connections → Webhooks).
  • About ten minutes. You'll build a flow from a ready-made template, paste its URL into FyneDesk, then add one step that posts the message.
Already pasted a Power Automate URL into FyneDesk? Then you've done the hard part. Skip to Part 3 — you only need to add the posting step.

Set it up

This is the exact path our team uses, end to end. It produces a simple, readable text message. (Want the message to name each event type, or prefer a formatted card? See the advanced options below.)

Part 1 — Create the flow from a template

Go to make.powerautomate.com and sign in. In the left menu choose Templates, type webhook in the search box, and open Send webhook alerts to a channel — the plain one, not the "(TEST)" versions. Click Continue (sign in again if asked).

The Power Automate Templates screen with webhook typed in the search box. Four templates are shown; the first, Send webhook alerts to a channel, is the one to open.

The template shows it will connect Teams → Microsoft Teams and generate a webhook URL. Before you click Create, set the Team and Channel you want the notifications posted to — this is easy to miss, and it matters.

The Send webhook alerts to a channel template screen, showing it will connect Teams to Microsoft Teams, with the connected Microsoft Teams account and a Continue button. The template setup with a Microsoft Teams Team dropdown set to a team, and a Microsoft Teams Channel dropdown, above a Create button. The channel value is redacted.

Choose your Team and channel, then click Create. When the flow opens, click Edit to start editing it.

Part 2 — Give the URL to FyneDesk

In the flow, click the first box, "When a Teams webhook request is received," and copy the HTTP URL it shows.

The When a Teams webhook request is received trigger expanded, showing a Who can trigger the flow dropdown set to Anyone and an HTTP URL field with a copy button. The URL value is redacted.

Then in FyneDesk, go to Admin Settings → Advanced → Webhooks and click Add webhook:

  • Name it something you'll recognise later, e.g. Microsoft Teams.
  • Paste the Power Automate URL into Endpoint URL (it must be an HTTPS link).
  • Leave ticket.created ticked — that's all you need to start. (You can add more events later.)
  • Click Save.
The FyneDesk Add webhook screen with a Name field set to Microsoft Teams, an Endpoint URL field for the Power Automate link, a list of events to send with ticket.created ticked, and a Save button.

Part 3 — Tell the flow what to post

This is the step that's easy to miss — and it's exactly why a test can say "sent" while nothing appears in Teams.

1. Delete the two prebuilt steps. The template adds an Initialize variable action (sometimes two) and an Attachments is null condition. Delete both — click the on each step, then Delete. Leaving them in is what triggers the "AdaptiveCard" error.

The flow editor showing the When a Teams webhook request is received trigger followed by two Initialize variable steps and an Attachments is null condition — the steps that should be deleted.

2. Add the posting action. Click the + under the trigger and choose Post message in a chat or channel (the Microsoft Teams connector). Set the dropdowns:

FieldSet to
Post asFlow bot
Post inChannel
TeamYour team
ChannelThe channel you want notifications in

3. Build the message. Click inside the Message box, click the blue fx (Insert expression) button, paste the expression below exactly, then click Add.

concat('New ticket ', triggerBody()?['data']?['ticket_number'], ' - ', triggerBody()?['data']?['title'], ' | Status: ', triggerBody()?['data']?['status'], ' | Priority: ', triggerBody()?['data']?['priority'], ' | https://app.fynedesk.io/tickets/', string(triggerBody()?['data']?['id']))
The Post message in a chat or channel action with Post as set to Flow bot, Post in set to Channel, a Team and Channel selected, and the Message box holding a single concat expression inserted via the fx expression editor shown on the right.

4. Save. Click Save (top right). You should see "Your flow is ready to go."

Two gotchas that waste hours
  • Always insert the expression with the fx button — never type it as plain text, and never wrap it in @{ }.
  • If you used a Copilot box at any point, clear that step's Comment field before saving. A long note there (over 256 characters) silently blocks the save.

Part 4 — Test

Create or update a real ticket in FyneDesk. A message appears in your Teams channel within a few seconds.

About the Send test button FyneDesk's Send test sends a small ping packet with no ticket number or title, so the test message looks sparse (mostly blank fields). That's expected. The real proof is to create or comment on an actual ticket and watch the channel.

Optional: label every event, or post a card

The expression above always begins with "New ticket". If you'd like the message to name the event (new comment, status change, and so on) or you'd prefer a formatted card, use one of the options below. The setup is identical — only the Message expression changes.

What FyneDesk sends

Your webhook can subscribe to four events. Here's the shape of each packet (values are examples).

ticket.created

{
  "event": "ticket.created",
  "timestamp": "2026-05-30T22:19:59",
  "organization": { "id": 173, "name": "SafePACS" },
  "data": {
    "id": 6381,
    "ticket_number": "INC004736",
    "title": "Printer not working",
    "description": "The 3rd floor printer is offline",
    "status": "New",
    "priority": "Medium",
    "ticket_type": "Incident",
    "source": "Email",
    "created_at": "2026-05-30T22:19:59"
  }
}

ticket.updated and ticket.status_changed use the same shape as above, plus updated_at, assigned_to, and assigned_team_id.

ticket.commented — note that the field names are slightly different here:

{
  "event": "ticket.commented",
  "timestamp": "2026-05-30T22:19:59",
  "organization": { "id": 173, "name": "SafePACS" },
  "data": {
    "ticket_id": 6381,
    "ticket_number": "INC004736",
    "ticket_title": "Printer not working",
    "ticket_status": "New",
    "content": "Any update on this?",
    "comment_id": 8809,
    "is_internal": false
  }
}
One flow handles all four The expressions below use coalesce(...) to fall back between the differing field names, so a single flow covers every event type. To use them, tick the extra events on your FyneDesk webhook (Part 2).

Option A — A richer text message

Instead of the single expression, type the layout below in the Message box. Everything that isn't a 〈placeholder〉 is plain text you type. For each 〈placeholder〉, click the fx button, paste the matching expression from the table, then click Add.

〈eventLabel〉  〈ticketNumber〉
〈title〉

Status: 〈status〉   •   Priority: 〈priority〉

〈message〉

Open in FyneDesk: 〈link〉
PlaceholderPaste this into the fx expression box
〈eventLabel〉if(equals(triggerBody()?['event'],'ticket.created'),'🎫 New ticket',if(equals(triggerBody()?['event'],'ticket.commented'),'💬 New comment',if(equals(triggerBody()?['event'],'ticket.status_changed'),'🔄 Status changed','✏️ Ticket updated')))
〈ticketNumber〉triggerBody()?['data']?['ticket_number']
〈title〉coalesce(triggerBody()?['data']?['title'],triggerBody()?['data']?['ticket_title'],'(no title)')
〈status〉coalesce(triggerBody()?['data']?['status'],triggerBody()?['data']?['ticket_status'],'-')
〈priority〉coalesce(triggerBody()?['data']?['priority'],'-')
〈message〉coalesce(triggerBody()?['data']?['content'],triggerBody()?['data']?['description'],'')
〈link〉concat('https://app.fynedesk.io/',if(equals(triggerBody()?['data']?['ticket_type'],'Service Request'),'requests/','tickets/'),string(coalesce(triggerBody()?['data']?['id'],triggerBody()?['data']?['ticket_id'])))

Option B — A formatted card

Prefer a card? Use the action Post card in a chat or channel and paste the following into the Adaptive Card field. It uses the same expressions, so it's the same data in a tidier layout.

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.2",
  "body": [
    {
      "type": "TextBlock",
      "size": "Medium",
      "weight": "Bolder",
      "text": "@{if(equals(triggerBody()?['event'],'ticket.created'),'🎫 New ticket',if(equals(triggerBody()?['event'],'ticket.commented'),'💬 New comment',if(equals(triggerBody()?['event'],'ticket.status_changed'),'🔄 Status changed','✏️ Ticket updated')))} @{triggerBody()?['data']?['ticket_number']}"
    },
    {
      "type": "TextBlock",
      "text": "@{coalesce(triggerBody()?['data']?['title'],triggerBody()?['data']?['ticket_title'],'(no title)')}",
      "wrap": true
    },
    {
      "type": "FactSet",
      "facts": [
        { "title": "Status", "value": "@{coalesce(triggerBody()?['data']?['status'],triggerBody()?['data']?['ticket_status'],'-')}" },
        { "title": "Priority", "value": "@{coalesce(triggerBody()?['data']?['priority'],'-')}" }
      ]
    },
    {
      "type": "TextBlock",
      "text": "@{coalesce(triggerBody()?['data']?['content'],triggerBody()?['data']?['description'],'')}",
      "wrap": true
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "Open in FyneDesk",
      "url": "@{concat('https://app.fynedesk.io/',if(equals(triggerBody()?['data']?['ticket_type'],'Service Request'),'requests/','tickets/'),string(coalesce(triggerBody()?['data']?['id'],triggerBody()?['data']?['ticket_id'])))}"
    }
  ]
}

Troubleshooting

Messages still aren't showing up — common fixes

You get an "AdaptiveCard" error, or the flow runs but never posts. The template's prebuilt Initialize variable and Attachments is null steps cause this. Delete both (Part 3, step 1), and post your message with a single Post message in a chat or channel action instead.

The flow won't save. If you tried Copilot at any point, clear that step's Comment field — a note longer than 256 characters silently blocks the save.

Nothing in Teams after a real ticket action. In Power Automate, open your flow and check Run history (the 28-day log). Each FyneDesk event should show a run. No runs at all means the FyneDesk webhook isn't pointed at this flow's URL, or isn't subscribed to that event — re-check it in FyneDesk. Runs show "Failed" means a step errored; click one to see which. Usually it's the Team or Channel not being selected, or the flow's owner lacking a Power Automate licence.

A message posts, but some fields are blank. Different events carry different fields (a comment has no priority, for example). The coalesce(...) expressions in the advanced options fall back gracefully, so a blank just means that event didn't include that field.

An expression shows a red error. Some trigger types expose the body as triggerOutputs()?['body'] instead of triggerBody(). If triggerBody() errors, swap it — for example, triggerOutputs()?['body']?['data']?['ticket_number'].

A note on security

Your Power Automate URL contains a secret signature (the sig=... part) — treat the whole URL like a password and don't share it. FyneDesk also signs every request with an X-FyneDesk-Signature header (HMAC-SHA256) if you ever want to verify authenticity inside the flow, though that's optional and not required to get messages flowing.

Prefer zero setup? There's now a native Teams app FyneDesk now posts ticket notifications to Teams natively — formatted, localized cards with no flow to build, on the Pro and Business plans. See Microsoft Teams notifications. Keep using this guide when you want full control over the message format or custom routing logic in Power Automate.

Frequently asked questions

FyneDesk says "sent successfully" but nothing appears in Teams. Why?

"Sent successfully" only means Microsoft received the data — Power Automate replies 202 Accepted the moment it gets a request. It doesn't mean a message was posted. Teams won't display the raw JSON on its own; your flow needs a Post message in a chat or channel action to format and post it.

Which Power Automate template should I use?

Open Templates, search for webhook, and choose Send webhook alerts to a channel — the plain one, not the "(TEST)" versions. It generates the webhook URL you paste into FyneDesk and lets you pick the Team and channel to post to.

Why do I get an "AdaptiveCard" error, or why does the flow never post?

The template ships with two prebuilt steps — an Initialize variable action and an Attachments is null condition — and those are what cause the AdaptiveCard error. Delete both, then add a single Post message in a chat or channel action with your own message expression.

Can FyneDesk post to Teams without Power Automate?

Yes — FyneDesk now has a native Microsoft Teams app that posts ticket notification cards straight to your channels, on the Pro and Business plans, with no flow to build. The webhook + Power Automate route on this page still works, and stays useful when you want full control over formatting and routing.

Which ticket events can I send to Teams?

A FyneDesk webhook can send ticket.created, ticket.updated, ticket.status_changed, and ticket.commented. The recommended setup uses ticket.created; the advanced expressions handle all four automatically, so one flow can cover every event.