Video file transfer from Airtable database to Microsoft Teams chatbot failing

I’m building a chatbot for Microsoft Teams using the Bot Framework SDK with Node.js. The bot pulls data from our Airtable database and displays it in Teams chat. I’m using the Teams Toolkit extension in VS Code for development and deployment.

The Problem:
I can’t get video files to transfer properly from Airtable to the Teams bot. Here’s what I’ve tried so far:

Method 1 - Direct attachment approach:
Using a custom function to handle internet-based attachments, but getting Unknown attachment type error.

async function fetchVideoAttachment(video_url) {
    return {
        name: "video.mp4",
        contentType: "video/mp4",
        contentUrl: video_url 
    };
}

Method 2 - Manifest configuration:
Set supportsFile: true in the manifest.json file but no change in behavior.

Method 3 - Video card creation:
Tried building a video card but getting Malformed Video card - Invalid aspect value error.

async function buildVideoCard(cardTitle, videoUrl) {
    return CardFactory.videoCard(
        cardTitle,
        [{ "url": videoUrl }],
        [{
            "type": 'openUrl',
            "title": 'Watch More',
            "value": 'https://example.com/videos'
        }],
        {
            "subtitle": 'Training Video',
            "text": 'Educational content for team training purposes'
        }
    );
}

await context.sendActivity({ attachments: [await buildVideoCard(videoTitle, videoUrl)] })

How I’m getting files from Airtable:

const data = await database(table_name).select({
    view: "Main view"
}).all();

data.forEach(async function (item) {
    videoFiles = item.get("VideoFiles")
    console.log(videoFiles)
    const message = { type: ActivityTypes.Message };
    message.attachments = [await fetchVideoAttachment(videoFiles.url)];
    context.sendActivity(message)
})

Sample output from Airtable:

[
  {
    id: 'attXy9bzGldMnS7uD',
    url: video_file_url,
    filename: 'TrainingVideo_720p_8mb.mp4',
    size: 8392841,
    type: 'video/mp4'
  }
]

All these methods work fine when I test in the Bot Framework emulator, but fail when deployed to actual Teams environment. What am I missing to make video attachments work properly in Teams?

Teams is really picky about video handling compared to the emulator. I’ve dealt with this exact headache multiple times.

The core issue is that Teams doesn’t process video attachments the same way as other platforms. Your fetchVideoAttachment function won’t work because Teams expects video content to be served with specific headers and CORS policies that Airtable doesn’t provide.

Here’s what actually works in production:

Skip the attachment approach entirely. Use an Adaptive Card with a video thumbnail and play button that opens the video in a new tab or triggers a video player modal. Teams handles this much better than trying to embed videos directly.

const videoCard = {
    type: "AdaptiveCard",
    body: [{
        type: "Image",
        url: thumbnailUrl,
        selectAction: {
            type: "Action.OpenUrl",
            url: videoFiles.url
        }
    }]
};

For the forEach async issue you have there - that’s definitely causing problems. Use for...of instead or Promise.all() to handle the async operations properly.

If you absolutely need inline video, you’ll need to proxy the Airtable URLs through your own service that adds the right headers. But honestly, the card approach gives users a better experience anyway.

Here’s a detailed walkthrough of handling file uploads in Teams bots that covers the technical requirements:

I ran into a similar issue last year when building a Teams bot for our training department. The main problem is that Teams has strict requirements for video attachments that differ from the Bot Framework emulator. First, your video URLs from Airtable need to be publicly accessible without authentication tokens. Teams won’t handle redirects or auth headers properly. I had to create a middleware service that downloads videos from Airtable and serves them from a public endpoint. Second issue is file size - Teams has a 20MB limit for inline video attachments, and even smaller files can timeout during rendering. Your 8MB file should work, but I’d recommend hosting videos externally and using adaptive cards with video thumbnails instead. For the ‘Unknown attachment type’ error, try setting the contentUrl as a direct download link rather than Airtable’s attachment URL. Also make sure you’re not using async/await incorrectly in your forEach loop - that can cause timing issues where the video hasn’t fully loaded when Teams tries to render it. The manifest supportsFile property only affects file uploads from users, not bot-sent attachments, so that won’t help here.

Been working with Teams bots for about three years now and video handling is definitely one of the trickier aspects. The issue you’re hitting is actually related to how Teams validates and processes media content differently from the emulator environment.

Your video card approach is closest to the right solution, but the aspect ratio error suggests you need to explicitly define the aspect property in your video card. Teams requires this for proper rendering. Try adding aspect: "16:9" or aspect: "4:3" to your video card configuration depending on your video format.

Another thing I discovered through trial and error is that Airtable’s attachment URLs often include query parameters and headers that Teams doesn’t handle gracefully. The URLs work fine for direct download but Teams media processor chokes on them. You might need to create a simple proxy endpoint that strips these parameters and serves the video with clean URLs.

Also worth checking if your Airtable URLs are serving the video with the correct Content-Type headers. Teams is very strict about MIME type validation for security reasons. The Bot Framework emulator is much more lenient, which is why it works there but fails in production.

One debugging tip - enable detailed logging in your Teams app and check the Activity feed in Teams admin center. It usually shows more specific error messages about why media attachments are being rejected.

teams has some weird caching issues with video urls too. had this problem few months ago and turns out airtable urls expire after certain time which breaks the video in teams chat even if it worked initially. try checking if your video urls have expiration tokens in them - thats probably why emulator works but teams doesnt. also your async forEach is definetly wrong, use map with promise.all instead

The problem you’re encountering is actually a common Teams limitation that caught me off guard when I first started working with Teams bots. Teams doesn’t support direct video file attachments through the Bot Framework the way other messaging platforms do.

What worked for me was switching to Hero Cards with video preview images instead of trying to send actual video attachments. Teams treats video files as documents rather than media content when sent through bot messages, which explains why you’re getting the unknown attachment type error.

Your video card implementation is on the right track but needs some tweaks. Remove the aspect property entirely - that’s what’s causing the malformed card error. Teams calculates aspect ratios automatically for video cards.

Another issue I discovered is that Airtable URLs contain authentication parameters that expire relatively quickly. Teams might be trying to access the video after these parameters have expired, causing failures in production even though they work during initial testing.

I ended up creating a simple endpoint that downloads videos from Airtable and serves them with permanent URLs. This solved both the authentication and the Teams compatibility issues. The performance impact was minimal since videos are cached after first download.