← Home

Guide

Let Microsoft 365 Tell Your Agent What Happened

This is not a chat channel. It is the opposite direction: Microsoft 365 notifying your agent that a meeting ended, a calendar entry moved, or a message landed — so the agent can act without anybody asking it to.

How This Differs From the Teams Bot

If what you want is people typing at your agent in Teams, you want the Teams bot instead. That is a person starting a conversation.

This listener is Microsoft telling your agent something changed, with no human involved. The clearest example, and the one it is built around today, is meeting summaries: a Teams meeting finishes and produces a transcript, Microsoft says so, the agent fetches the transcript and posts a summary back into Teams. Nobody typed anything.

The same listener handles other Microsoft 365 event sources — chat messages, calendar events — using the same plumbing.

What You Need

  • A registered Microsoft Graph application, which is an Azure administration task on your side.
  • A public HTTPS address that Microsoft can reach. Microsoft will not deliver to private endpoints and will not deliver over plain HTTP.
  • A strong random shared secret, which does more work here than you might expect.

The Shared Secret Is the Lock

Every notification Microsoft sends includes a string you chose when you created the subscription. The listener compares it and rejects anything that does not match.

That comparison is the primary authentication for this endpoint. There is no signature to verify beyond it, which means the secret should be long and random — generate it, do not invent it — and should be treated like a password. The listener refuses to start at all if you have not set one, which is the right call.

If the value ever drifts between what you configured and what the subscription was registered with, every notification is rejected and nothing arrives. That is the most common cause of a listener that appears to work and ingests nothing.

Locking It Down Further

For production you can restrict the listener to Microsoft's published source address ranges, so nothing else on the internet can even attempt a delivery. If you bind the listener to a public address, this restriction is mandatory — it refuses to start otherwise, rather than sitting open.

The simpler arrangement, and the one that fits hosted instances, is to keep the listener bound locally and let a reverse proxy handle the public side and the certificate. The listener speaks plain HTTP by design and expects TLS to be terminated in front of it.

If you do use address restrictions, review Microsoft's published ranges periodically. They change, and when they do the symptom is real notifications being refused.

Narrowing What It Accepts

By default the listener accepts any resource type. You can give it a list of the resource paths you actually expect, which means a subscription you forgot about cannot start driving your agent. Worth setting.

Repeated notifications for the same event are recognised and dropped, so Microsoft retrying does not cause the agent to act twice.

Subscriptions Expire

This is the thing that catches people weeks later, so it gets its own section. Microsoft Graph subscriptions have a lifetime and stop delivering when they reach it. Nothing errors. The agent simply stops hearing about meetings, and unless you are watching for it, the first sign is somebody asking why the summaries stopped.

Whatever you set up, set up the renewal alongside it.

Getting It Working

The first hurdle is the validation handshake. When you create a subscription, Microsoft immediately calls your address with a token and expects it echoed back verbatim within ten seconds. If your public address is wrong, unreachable, or fronted by something that rewrites the response, the subscription is never created and you get an error at that point rather than later.

Once that passes, the ordering is: create the subscription with your secret, confirm notifications are arriving, then confirm the agent is doing something with them. Those are three separate failure points and worth checking in that order.

Troubleshooting

  • Subscription validation fails. The address is not reachable, the path does not match, or the handshake response is not being echoed back cleanly.
  • Notifications arrive but nothing happens. The shared secret does not match what the subscription registered, or the resource is not in your accepted list.
  • Everything is refused. Either a secret mismatch or an address restriction that is too narrow to include Microsoft's current ranges.
  • It refuses to start on a public address. That is the deliberate guard — add the address restriction or bind it locally behind a proxy.
  • It went quiet after a few weeks. The subscription expired. See above.

Need a Hand?

The Azure application registration is yours to do, but the listener and the public path are ours. Contact support from your dashboard and we will wire up the endpoint. Do not send the shared secret or your application credentials in chat — we will tell you where to put them.