Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with Microsoft Teams

To send notifications from Lovable to Microsoft Teams, create an Incoming Webhook in your Teams channel, store the webhook URL in Cloud → Secrets, and build an Edge Function that POSTs formatted Adaptive Cards to Teams. Unlike Slack — which has a native Lovable connector — Teams requires manual Edge Function setup. This pattern works for order alerts, error notifications, and approval workflows.

What you'll learn

  • How to create an Incoming Webhook in a Microsoft Teams channel
  • How to store the Teams webhook URL securely in Lovable Cloud → Secrets
  • How to write a Deno Edge Function that sends formatted Adaptive Cards to Teams
  • How to trigger Teams notifications from user actions or database events in your Lovable app
  • How Teams Incoming Webhooks differ from the Microsoft Graph API and when to use each
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read25 minutesCommunicationMarch 2026RapidDev Engineering Team
TL;DR

To send notifications from Lovable to Microsoft Teams, create an Incoming Webhook in your Teams channel, store the webhook URL in Cloud → Secrets, and build an Edge Function that POSTs formatted Adaptive Cards to Teams. Unlike Slack — which has a native Lovable connector — Teams requires manual Edge Function setup. This pattern works for order alerts, error notifications, and approval workflows.

Send Microsoft Teams notifications from Lovable using Incoming Webhooks

Unlike Slack, which is available as a native shared connector in Lovable's Settings → Connectors panel, Microsoft Teams requires manual setup. There is no Teams connector in Lovable's built-in library, which means you need to wire it yourself using an Edge Function. The good news is that Teams' Incoming Webhook feature makes this straightforward — a webhook URL is all you need to start posting messages, and the entire setup takes about 25 minutes.

Teams supports two integration approaches. The simpler approach uses Incoming Webhooks: you create a webhook directly in a Teams channel, get a URL, and POST formatted message cards to that URL from your Edge Function. No OAuth, no token refresh, no Microsoft Graph API — just a URL and a JSON payload. This is the right choice for one-way notifications from your app to your team, like new order alerts, error reports, low-inventory warnings, or deployment notifications.

The more powerful approach uses the Microsoft Graph API with OAuth2 credentials — this lets you read messages, create channels, manage teams members, and perform two-way communication. It requires registering an app in Azure Active Directory and handling token refresh. For most Lovable integrations, Incoming Webhooks are sufficient and dramatically simpler. This guide covers the webhook approach with a note on Graph API for when you need it.

Teams Adaptive Cards are the recommended message format. Unlike plain text or legacy MessageCard format, Adaptive Cards render structured, visually appealing messages with headings, facts, action buttons, and images — and they are supported across all Teams clients. Lovable's AI can generate Adaptive Card JSON payloads from natural language descriptions of what your notification should contain.

Integration method

Edge Function Integration

Microsoft Teams has no native Lovable connector. Notifications are sent via Teams Incoming Webhooks or the Microsoft Graph API, both of which are called from a Lovable Edge Function. The webhook URL or Graph API credentials are stored in Cloud → Secrets, and the Edge Function constructs and POSTs Adaptive Card payloads to Teams channels.

Prerequisites

  • A Lovable project with at least one deployed app (Edge Functions require Lovable Cloud)
  • Microsoft Teams access with permission to add connectors to a channel (Team Owner or Member with Manage Channel permission)
  • A Teams channel where you want to receive notifications (create a dedicated #alerts or #notifications channel for clarity)
  • Basic understanding of what an Edge Function does in Lovable (server-side Deno function that runs on Lovable Cloud)

Step-by-step guide

1

Create an Incoming Webhook connector in your Teams channel

The first step happens entirely in Microsoft Teams, not in Lovable. You need to create an Incoming Webhook in the Teams channel where you want to receive notifications. This generates a unique URL that your Edge Function will POST to. Open Microsoft Teams and navigate to the channel where you want notifications to appear. Click the three-dot menu (...) next to the channel name in the sidebar. Select 'Manage channel' from the dropdown. In the channel settings panel, find the Connectors section and click 'Edit' or look for the 'Connectors' option. If you are in newer Teams (Teams 2.0), the path may be slightly different: click the channel name → More options → Connectors. In the Connectors dialog, search for 'Incoming Webhook' in the search box. Click the 'Incoming Webhook' connector and then click 'Configure'. Give your webhook a descriptive name — something like 'Lovable App Notifications' — so your team knows what it is. Optionally, upload a small icon (your app logo works well) that will appear next to notifications posted by this webhook. Click 'Create'. Teams will generate a unique webhook URL that looks like: https://yourcompany.webhook.office.com/webhookb2/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/IncomingWebhook/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Copy this URL immediately. It is your private channel endpoint — anyone with this URL can post messages to your Teams channel, so treat it like a password. Click 'Done' to save the connector.

Pro tip: Create a dedicated Teams channel for app notifications (e.g., #app-notifications or #alerts) rather than posting to a general chat channel. This keeps your team's conversations separate from automated messages.

Expected result: A unique Incoming Webhook URL is created for your Teams channel. The channel now shows 'Incoming Webhook' in its Connectors list. Messages sent to this URL will appear as posts in the channel.

2

Store the Teams webhook URL in Lovable Cloud Secrets

With the webhook URL copied, store it in Lovable's Cloud Secrets panel. The webhook URL is sensitive — it grants anyone who has it the ability to post messages to your Teams channel on behalf of your connector. Storing it as a secret ensures it stays server-side, inaccessible to your frontend JavaScript and absent from your Git repository. In your Lovable project, click the '+' icon at the top of the editor (next to the Preview label). In the Cloud panel that opens, click the 'Secrets' tab. Click 'Add new secret'. In the Name field, type TEAMS_WEBHOOK_URL exactly. In the Value field, paste the full Incoming Webhook URL you copied from Teams. Click Save. If you plan to send notifications to multiple Teams channels (for example, one channel for orders and another for errors), add each webhook as a separate secret: TEAMS_ORDERS_WEBHOOK_URL, TEAMS_ALERTS_WEBHOOK_URL, and so on. This naming convention makes it obvious in your Edge Function code which channel each notification goes to. As always with Lovable secrets: never paste the webhook URL directly into Lovable's chat prompt. Even though a webhook URL is not an API key in the traditional sense, it is still a credential that should not appear in code or chat history. The secret panel is the only appropriate storage location.

Pro tip: Teams Incoming Webhook URLs do not expire by default, but you can delete and recreate them in the Teams channel settings at any time if a URL is compromised. Treat them as you would any other credential.

Expected result: TEAMS_WEBHOOK_URL appears in your Cloud → Secrets panel with its value masked. Your Edge Function in the next step will access it via Deno.env.get('TEAMS_WEBHOOK_URL').

3

Create the Teams notification Edge Function

Now create the Edge Function that formats and sends notifications to Teams. The function will receive notification data from your frontend, construct an Adaptive Card payload, and POST it to the Teams webhook URL from Secrets. Adaptive Cards are the recommended message format for Teams. They support rich formatting: headings, fact tables, images, action buttons, and conditional visibility. The Adaptive Card format is JSON, and Teams renders it natively on all platforms (desktop, mobile, web). The code example below shows a complete Adaptive Card for a generic notification, which you can customize for your specific use case. Important: Teams Incoming Webhooks accept two payload formats. The legacy format uses 'type': 'MessageCard' — this still works but is being deprecated. The modern format uses Adaptive Card syntax wrapped in a specific Teams container. The code below uses the modern format. Some older Teams clients may fall back to a plain text summary if Adaptive Cards are not supported, which is why the payload includes a 'summary' field. The function handles CORS headers for browser calls, validates that the webhook URL is configured, and returns appropriate error messages if the Teams API rejects the request. Teams webhooks return a '1' string response on success (not a JSON object), so the success check is string-based.

Lovable Prompt

Create an Edge Function called notify-teams that accepts a POST request with { title, message, severity, facts, actionUrl, actionLabel } where facts is an array of { name, value } pairs. It should retrieve TEAMS_WEBHOOK_URL from Deno environment variables and POST an Adaptive Card to Teams. Include CORS headers and handle the OPTIONS preflight. Return a success or error response.

Paste this in Lovable chat

supabase/functions/notify-teams/index.ts
1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
2
3const corsHeaders = {
4 'Access-Control-Allow-Origin': '*',
5 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
6}
7
8const severityColors: Record<string, string> = {
9 info: 'Good',
10 warning: 'Warning',
11 high: 'Attention',
12 critical: 'Attention',
13}
14
15serve(async (req) => {
16 if (req.method === 'OPTIONS') {
17 return new Response('ok', { headers: corsHeaders })
18 }
19
20 try {
21 const { title, message, severity = 'info', facts = [], actionUrl, actionLabel } = await req.json()
22
23 const webhookUrl = Deno.env.get('TEAMS_WEBHOOK_URL')
24 if (!webhookUrl) {
25 throw new Error('TEAMS_WEBHOOK_URL secret is not configured')
26 }
27
28 const adaptiveCard = {
29 type: 'message',
30 attachments: [
31 {
32 contentType: 'application/vnd.microsoft.card.adaptive',
33 contentUrl: null,
34 content: {
35 '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
36 type: 'AdaptiveCard',
37 version: '1.5',
38 body: [
39 {
40 type: 'TextBlock',
41 text: title,
42 size: 'Large',
43 weight: 'Bolder',
44 color: severityColors[severity] || 'Default',
45 },
46 {
47 type: 'TextBlock',
48 text: message,
49 wrap: true,
50 },
51 ...(facts.length > 0
52 ? [{
53 type: 'FactSet',
54 facts: facts.map((f: { name: string; value: string }) => ({
55 title: f.name,
56 value: f.value,
57 })),
58 }]
59 : []),
60 ],
61 actions: actionUrl
62 ? [{
63 type: 'Action.OpenUrl',
64 title: actionLabel || 'View Details',
65 url: actionUrl,
66 }]
67 : [],
68 },
69 },
70 ],
71 }
72
73 const response = await fetch(webhookUrl, {
74 method: 'POST',
75 headers: { 'Content-Type': 'application/json' },
76 body: JSON.stringify(adaptiveCard),
77 })
78
79 const responseText = await response.text()
80 if (!response.ok || responseText === '0') {
81 throw new Error(`Teams webhook failed: ${response.status} - ${responseText}`)
82 }
83
84 return new Response(
85 JSON.stringify({ success: true }),
86 { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
87 )
88 } catch (error) {
89 return new Response(
90 JSON.stringify({ error: error.message }),
91 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
92 )
93 }
94})

Pro tip: Teams Incoming Webhooks return the string '1' on success and '0' on failure. The code above checks for both the HTTP status and the response body to detect failures correctly.

Expected result: Lovable creates and deploys supabase/functions/notify-teams/index.ts. The function appears in Cloud → Edge Functions. It accepts POST requests with notification data and sends Adaptive Cards to your Teams channel.

4

Trigger Teams notifications from your app

With the Edge Function deployed, connect it to meaningful events in your Lovable app. Use the Supabase client's functions.invoke() to call the notification function from your React components or from other Edge Functions. The most impactful places to add Teams notifications are: after a successful payment (notify the sales team), when a user submits a support request (alert the support channel), when a scheduled task completes or fails (inform the engineering team), or when a form submission requires human review (ping the moderation team). For React component triggers, call the function in an event handler. For automated triggers based on database changes, consider adding the Teams notification call inside other Edge Functions — for example, your Stripe webhook handler can call notify-teams after processing a payment. The code example below shows how to call the notification function from a React component after a user action. The invoke() call is non-blocking — wrap it in a try-catch and do not let notification failures interrupt the user's main flow. If Teams is temporarily unavailable, your app should continue working normally.

Lovable Prompt

After a user submits the contact form in my app, call the notify-teams Edge Function using supabase.functions.invoke() to send a Teams notification with the title 'New Contact Form Submission', the user's message and email as facts, and a link to the admin panel. Handle errors silently so the form submission still succeeds even if the Teams notification fails.

Paste this in Lovable chat

src/lib/notify.ts
1import { supabase } from '@/lib/supabase'
2
3const notifyTeams = async (params: {
4 title: string
5 message: string
6 severity?: 'info' | 'warning' | 'high'
7 facts?: Array<{ name: string; value: string }>
8 actionUrl?: string
9 actionLabel?: string
10}) => {
11 try {
12 const { error } = await supabase.functions.invoke('notify-teams', {
13 body: params,
14 })
15 if (error) console.error('Teams notification failed:', error)
16 } catch (err) {
17 // Silently fail — notification should not break the main flow
18 console.error('Teams notification error:', err)
19 }
20}
21
22// Example usage after a form submission:
23const handleContactSubmit = async (formData: ContactFormData) => {
24 // 1. Save to database
25 const { error } = await supabase.from('contact_submissions').insert(formData)
26 if (error) throw error
27
28 // 2. Notify Teams (non-blocking)
29 notifyTeams({
30 title: 'New Contact Form Submission',
31 message: formData.message.substring(0, 200),
32 severity: 'info',
33 facts: [
34 { name: 'From', value: formData.email },
35 { name: 'Subject', value: formData.subject },
36 { name: 'Submitted', value: new Date().toLocaleString() },
37 ],
38 actionUrl: 'https://myapp.com/admin/contacts',
39 actionLabel: 'View in Admin',
40 })
41
42 // 3. Continue with success flow
43 return { success: true }
44}

Pro tip: Create a shared notifyTeams() helper function in src/lib/notify.ts that all components and Edge Functions can import. This keeps the invoke logic in one place and makes it easy to add retry logic or additional notification channels later.

Expected result: When the triggering event occurs in your app, an Adaptive Card appears in your Teams channel within seconds. Cloud → Logs shows the notify-teams Edge Function executed successfully.

Common use cases

Send new order notifications to a sales team channel

When a customer completes a purchase in your Lovable app, post an Adaptive Card to your Teams #sales channel with the order details — customer name, items purchased, order total, and a link to the admin panel. This keeps the sales team informed in real time without checking a separate dashboard.

Lovable Prompt

Create an Edge Function called notify-teams-order that accepts a POST request with { customerName, orderTotal, items, orderId } and sends an Adaptive Card to the Teams webhook URL stored as TEAMS_WEBHOOK_URL in secrets. The card should have a heading 'New Order Received', show customer name and total as facts, list the items, and include an action button linking to /admin/orders/{orderId}.

Copy this prompt to try it in Lovable

Alert a DevOps channel when an Edge Function throws an error

Add error monitoring to your Edge Functions by catching unhandled exceptions and posting them to a Teams #alerts channel. Include the function name, error message, stack trace, and timestamp so your team can respond quickly without setting up external monitoring tools.

Lovable Prompt

Update my existing Edge Functions to catch any unhandled errors and send an alert to Teams using TEAMS_WEBHOOK_URL from secrets. The alert should be an Adaptive Card with severity 'High', include the function name, error message, and timestamp. Create a shared notifyTeamsError helper function that all Edge Functions can call from their catch blocks.

Copy this prompt to try it in Lovable

Post approval requests to a Teams channel for content moderation

When users submit content that needs human review (job listings, product descriptions, user profiles), post an Adaptive Card to a #moderation Teams channel. Include the content preview, submitter details, and Approve/Reject action buttons that call back to your Lovable Edge Function to update the database record.

Lovable Prompt

Create a moderation workflow: when a new listing is submitted in my app, send an Adaptive Card to Teams via TEAMS_WEBHOOK_URL with the listing title, description preview, submitter name, and two action buttons — Approve and Reject. Each button should trigger a callback to my Edge Function at /functions/v1/moderate-listing with the listingId and decision.

Copy this prompt to try it in Lovable

Troubleshooting

Teams webhook returns '0' or HTTP 400 with 'Summary or Text is required'

Cause: The Adaptive Card payload is missing a required 'summary' field at the top level. Teams requires a text summary for accessibility and notification previews even when using Adaptive Cards.

Solution: Add a 'summary' field to the top-level payload object alongside the 'attachments' array. This summary text appears in Teams notification banners and activity feeds. Update the adaptiveCard object to include: { type: 'message', summary: title, attachments: [...] }.

typescript
1const adaptiveCard = {
2 type: 'message',
3 summary: title, // Add this line
4 attachments: [
5 // ... your existing attachments
6 ],
7}

Teams posts appear but Adaptive Cards render as plain text instead of formatted cards

Cause: The Teams client version or channel type does not support Adaptive Cards, or the payload format uses the legacy MessageCard type which renders differently.

Solution: Verify you are using the modern Adaptive Card format with contentType: 'application/vnd.microsoft.card.adaptive'. Also check that the Adaptive Card version is set to '1.2' or higher — some Teams tenants may not support the latest version. Try lowering the version to '1.2' for maximum compatibility. If the issue persists, ensure the Teams channel is a standard channel (not a private channel or shared channel, which have different connector behavior).

typescript
1// Change version to 1.2 for maximum Teams client compatibility:
2content: {
3 '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
4 type: 'AdaptiveCard',
5 version: '1.2', // Lower version for compatibility
6 // ... rest of card
7}

Edge Function returns 'TEAMS_WEBHOOK_URL secret is not configured' even after adding the secret

Cause: Secrets added after an Edge Function was last deployed are not automatically available — functions need to be redeployed to pick up new environment variables.

Solution: After adding the TEAMS_WEBHOOK_URL secret in Cloud → Secrets, trigger a redeployment of the Edge Function. In Lovable, the easiest way to do this is to open a chat prompt and ask Lovable to 'make a minor update to the notify-teams Edge Function to redeploy it'. Alternatively, you can add an innocuous comment line to the function code to trigger a new deployment.

Teams shows the notification but the Incoming Webhook connector was deleted from the channel

Cause: A Teams admin or channel owner removed the Incoming Webhook connector from the channel settings, invalidating the webhook URL stored in your secrets.

Solution: Go to Teams → channel → Manage channel → Connectors and check if Incoming Webhook still appears. If it was deleted, you need to create a new one following Step 1 of this guide. The new webhook will have a different URL — update the TEAMS_WEBHOOK_URL secret in Cloud → Secrets with the new URL. No code changes are required since the function reads the URL from the secret at runtime.

Best practices

  • Create dedicated Teams channels for different notification categories (e.g., #app-alerts, #new-orders, #support-requests) rather than posting everything to a general channel — this prevents notification fatigue.
  • Always include a 'summary' field in your Teams payload alongside the Adaptive Card attachments for accessibility and notification banner support.
  • Store separate webhook URLs for different channels as separate secrets (TEAMS_ORDERS_WEBHOOK_URL, TEAMS_ALERTS_WEBHOOK_URL) rather than one URL for everything.
  • Never let Teams notification failures block your main application flow — always wrap notify calls in try-catch and fail silently if Teams is temporarily unreachable.
  • Use Adaptive Card severity colors (Good for info, Warning for caution, Attention for critical) consistently across all your notifications so team members can immediately gauge urgency at a glance.
  • For high-volume notifications, implement rate limiting in your Edge Function — Teams Incoming Webhooks have a rate limit of roughly 4 requests per second, and exceeding it results in 429 throttling errors.
  • Test your Adaptive Card designs using the Adaptive Cards Designer at adaptivecards.io/designer before implementing them in your Edge Function, to see exactly how they will render across different Teams clients.

Alternatives

Frequently asked questions

Is there a native Lovable connector for Microsoft Teams?

No — as of March 2026, Microsoft Teams does not have a native Lovable shared connector. Slack is the team communication tool with a native connector in Lovable's Settings → Connectors panel. For Teams, you need to manually create an Incoming Webhook in Teams and build an Edge Function in Lovable to call it. This guide covers the complete process.

What is the difference between Teams Incoming Webhooks and the Microsoft Graph API?

Incoming Webhooks are one-way: your app can POST messages to a Teams channel but cannot read messages or take other actions. They are simple to set up (just a URL, no OAuth) and are perfect for notifications and alerts. The Microsoft Graph API supports two-way communication — reading messages, creating channels, managing team members — but requires registering an Azure AD application, handling OAuth2 flows, and managing token refresh. For most Lovable notification use cases, Incoming Webhooks are sufficient and much simpler.

Can I send Teams notifications from database triggers without user action?

Yes — the best pattern is to call the notify-teams Edge Function from within another Edge Function that processes database events. For example, your Stripe webhook handler can notify Teams after a payment. You can also create a Supabase database function trigger that calls the Edge Function when specific table rows are inserted or updated. Lovable's AI can help you set up this pattern if you describe the database event you want to monitor.

How do I add interactive Approve/Reject buttons to Teams notifications?

Add 'Action.Submit' actions to your Adaptive Card and configure them to POST data to your Edge Function's URL. Teams will send a POST request to your actionUrl when a user clicks the button, including the card data. Your Edge Function then processes the action (e.g., updates the database record and sends a confirmation message). Note that Action.Submit in Incoming Webhook messages has limitations — for full interactivity, you may need to use Azure Bot Service or Power Automate flows.

Will Teams notifications still work if my Lovable app is paused or in maintenance mode?

Teams notifications are sent by your Edge Functions, which run on Lovable Cloud infrastructure. As long as the Edge Function is deployed and Lovable Cloud is operational, notifications will be sent regardless of whether your app's frontend is being accessed. If Lovable Cloud has an outage, both your app and notifications will be unavailable until service is restored.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.