in packages/app/main/src/server/routes/directLine/handlers/upload.ts [48:138]
export function createUploadHandler(emulatorServer: EmulatorRestServer) {
const {
logger: { logMessage },
state,
} = emulatorServer;
return (req: Request, res: Response, next: Next): any => {
if (req.params.conversationId.includes('transcript')) {
res.end();
next();
return;
}
const conversation: Conversation = (req as any).conversation;
const botEndpoint: BotEndpoint = (req as any).botEndpoint;
if (!conversation) {
res.send(HttpStatus.NOT_FOUND, 'conversation not found');
res.end();
logMessage(req.params.conversationId, textItem(LogLevel.Error, 'Cannot upload file. Conversation not found.'));
next();
return;
}
if (req.getContentType() !== 'multipart/form-data' || (req.getContentLength() === 0 && !req.isChunked())) {
next();
return;
}
const form = new Formidable.IncomingForm({ keepExtensions: true, multiples: true });
// TODO: Override form.onPart handler so it doesn't write temp files to disk.
form.parse(req, async (err: any, fields: any, files: any) => {
try {
const activity = JSON.parse(fs.readFileSync(files.activity.path, 'utf8'));
let uploads = files.file;
if (!Array.isArray(uploads)) {
uploads = [uploads];
}
if (uploads && uploads.length) {
const serviceUrl = await emulatorServer.getServiceUrl(botEndpoint.botUrl);
activity.attachments = [];
uploads.forEach(upload1 => {
const name = (upload1 as any).name || 'file.dat';
const type = upload1.type;
const path = upload1.path;
const base64EncodedContent = fs.readFileSync(path, { encoding: 'base64' });
const base64Buf = Buffer.from(base64EncodedContent, 'base64');
const attachmentData: AttachmentData = {
type,
name,
originalBase64: new Uint8Array(base64Buf),
thumbnailBase64: new Uint8Array(base64Buf),
};
const attachmentId = state.attachments.uploadAttachment(attachmentData);
const attachment: Attachment = {
name,
contentType: type,
contentUrl: `${serviceUrl}/v3/attachments/${attachmentId}/views/original`,
};
activity.attachments.push(attachment);
});
try {
const { updatedActivity, statusCode, response } = await conversation.postActivityToBot(activity, true);
if (~~statusCode === 0 && ~~statusCode > 300) {
res.send(statusCode || HttpStatus.INTERNAL_SERVER_ERROR, await response.text());
res.end();
} else {
res.send(statusCode, { id: updatedActivity.id });
res.end();
WebSocketServer.sendToSubscribers(conversation.conversationId, updatedActivity);
}
} catch (err) {
sendErrorResponse(req, res, next, err);
}
} else {
res.send(HttpStatus.BAD_REQUEST, 'no file uploaded');
res.end();
}
} catch (e) {
sendErrorResponse(req, res, next, e);
}
next();
});
};
}