UNPKG

@microsoft/teams-ai

Version:

SDK focused on building AI based applications for Microsoft Teams.

124 lines 5.87 kB
"use strict"; /** * @module teams-ai */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TeamsAttachmentDownloader = void 0; const axios_1 = __importDefault(require("axios")); const botframework_connector_1 = require("botframework-connector"); /** * Downloads attachments from Teams using the bots access token. */ class TeamsAttachmentDownloader { _options; _httpClient; /** * Creates a new instance of the `TeamsAttachmentDownloader` class. * @param {TeamsAttachmentDownloader} options - Options for the `TeamsAttachmentDownloader` class. */ constructor(options) { this._options = options; this._httpClient = axios_1.default.create(); } /** * Download any files relative to the current user's input. * @template TState - Type of the state object passed to the `TurnContext.turnState` method. * @param {TurnContext} context Context for the current turn of conversation. * @param {TState} state Application state for the current turn of conversation. * @returns {Promise<InputFile[]>} Promise that resolves to an array of downloaded input files. */ async downloadFiles(context, state) { // Filter out HTML attachments const attachments = context.activity.attachments?.filter((a) => !a.contentType.startsWith('text/html')); if (!attachments || attachments.length === 0) { return Promise.resolve([]); } let accessToken = ''; // If authentication is enabled, get access token if ((await this._options.adapter.credentialsFactory?.isAuthenticationDisabled()) !== true) { // Download all attachments accessToken = await this.getAccessToken(); } const files = []; for (const attachment of attachments) { const file = await this.downloadFile(attachment, accessToken); if (file) { files.push(file); } } return files; } /** * @private * @param {Attachment} attachment - Attachment to download. * @param {string} accessToken - Access token to use for downloading. * @returns {Promise<InputFile>} - Promise that resolves to the downloaded input file. */ async downloadFile(attachment, accessToken) { if ((attachment.contentUrl && attachment.contentUrl.startsWith('https://')) || (attachment.contentUrl && attachment.contentUrl.startsWith('http://localhost'))) { let headers; if (accessToken.length > 0) { // Build request for downloading file if access token is available headers = { Authorization: `Bearer ${accessToken}` }; } const response = await this._httpClient.get(attachment.contentUrl, { headers, responseType: 'arraybuffer' }); // Convert to a buffer const content = Buffer.from(response.data, 'binary'); // Fixup content type let contentType = attachment.contentType; if (contentType === 'image/*') { contentType = 'image/png'; } // Return file return { content, contentType, contentUrl: attachment.contentUrl }; } else { return { content: Buffer.from(attachment.content), contentType: attachment.contentType, contentUrl: attachment.contentUrl }; } } /** * @private * @returns {Promise<string>} - Promise that resolves to the access token. */ async getAccessToken() { // Normalize the ToChannelFromBotLoginUrlPrefix (and use a default value when it is undefined). // If non-public (specific tenant) login URL is to be used, make sure the full url including tenant ID is provided to TeamsAdapter on setup. const toChannelFromBotLoginUrl = (this._options.adapter.botFrameworkAuthConfig?.ToChannelFromBotLoginUrl || botframework_connector_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix + botframework_connector_1.AuthenticationConstants.DefaultChannelAuthTenant).toLowerCase(); let audience = this._options.adapter.botFrameworkAuthConfig?.ToChannelFromBotOAuthScope; // If there is no toChannelFromBotLoginUrl set on the provided ConfigurationBotFrameworkAuthenticationOptions, or it starts with 'https://login.microsoftonline.com/', the bot is operating in Public Azure. // So we use the Public Azure audience or the specified audience. if (toChannelFromBotLoginUrl.startsWith(botframework_connector_1.AuthenticationConstants.ToChannelFromBotLoginUrlPrefix)) { audience = audience ?? botframework_connector_1.AuthenticationConstants.ToChannelFromBotOAuthScope; } else if (toChannelFromBotLoginUrl.startsWith(botframework_connector_1.GovernmentConstants.ToChannelFromBotLoginUrlPrefix)) { // Or if the bot is operating in US Government Azure, use that audience. audience = audience ?? botframework_connector_1.GovernmentConstants.ToChannelFromBotOAuthScope; } const appCreds = (await this._options.adapter.credentialsFactory.createCredentials(this._options.botAppId, audience, toChannelFromBotLoginUrl, true)); return appCreds.getToken(); } } exports.TeamsAttachmentDownloader = TeamsAttachmentDownloader; //# sourceMappingURL=TeamsAttachmentDownloader.js.map