@microsoft/teams-ai
Version:
SDK focused on building AI based applications for Microsoft Teams.
124 lines • 5.87 kB
JavaScript
;
/**
* @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