Configuring an Email Activity to Send Documents With Original File Names
Issue
Is it possible to configure an Email activity to send imported documents with the original file names as they were imported?
Solution
No, not with out-of-the-box functionality.
The attachments field of the Email activity can accept Folder or document variables, or explicit file paths. If an explicit file path is used, then the attachment in the resulting email will have the name of the file as expected. However when a folder or document variable is used, an auto generated file name is used, even if the document originated from file import or email import where an original file name was present. In situations where the imported file is not a known mime type, then the resulting email attachment also will have no file extension, regardless of the file extension present in the original name.
As an alternative, it is possible use the API to determine the original name, save to disk, then email the saved file. This will result in an email that contains attachments with the original names imported from file import or email import. Sample code to demonstrate saving with original name is included at the end of this document.
Save source file with original name
Ensure that the core worker service user has appropriate permissions to the save location.
Testing a job shows the resulting variable with paths where the files were written:
Send email from file location
The string array (mapped to a Dynamic Complex variable with one string column) returned from SaveSourceFiles can be used directly in the email activity’s attachment field.
The resulting email contains each attachment with original name, and inherently also includes the original extension even though these are not known mime types.
Sample code for saving source file with original name
This code is provided as an example for a developer to assess and make any necessary modifications to meet their own needs, in accordance with API documentation included in the product.
Download source: SaveSourceFile.cs
using Agility.Sdk.Model.Capture; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using TotalAgility.Sdk; namespace KtaCase { public class SaveSourceFile { /// <summary> /// This tries to save the source file of a document to the given folder, using the original file name stored in /// the text extension named "Kofax.CEBPM.FileName" if it exists. If the text extension does not exist, then the filename is /// "UnknownOriginalName-" + documentId (no file extension). /// If the input files for the document were tiffs, then no source file exists and a multi-page tiff is saved (with extension tiff). /// </summary> /// <param name="sessionId"></param> /// <param name="documentId"></param> /// <param name="folderPath"></param> /// <returns></returns> public string SaveSourceFile(string sessionId, string documentId, string folderPath) { var ds = new CaptureDocumentService(); string OriginalFileName = "UnknownOriginalName-" + documentId; try { OriginalFileName = ds.GetTextExtension(sessionId, null,documentId, "Kofax.CEBPM.FileName"); } catch (Exception ex) { Debug.Print($"Error getting original name: {ex.Message}"); } var filePath = Path.Combine(folderPath, OriginalFileName); Debug.Print($"Writing source file to path: {filePath}"); DocumentSourceFile sourceFile = null; try { // Get the source file which will not exist if the source was tif sourceFile = ds.GetSourceFile(sessionId, null, documentId); } catch (Exception ex) { Debug.Print($"Could not get source file: {ex.Message}"); } if (sourceFile!=null && sourceFile.SourceFile!=null) { Debug.Print($"Source file mime type: {sourceFile.MimeType}"); File.WriteAllBytes(filePath, sourceFile.SourceFile); } else { // If no source file, get doc file as multipage tif filePath=ds.GetDocumentAsFile(sessionId, documentId, folderPath, OriginalFileName); } return filePath; } /// <summary> /// Calls SaveSourceFile for each document in a folder and returns an array with the resulting /// file paths. Use SaveSourceFilesOpmt for an OPMT system. /// </summary> /// <param name="sessionId"></param> /// <param name="folderId"></param> /// <param name="folderPath"></param> /// <returns>array with the resulting file paths. Suitable for mapping to a dynamic complex variable with one string column, /// and mapping to the attachment field of an email activity.</returns> public string[] SaveSourceFiles(string sessionId, string folderId, string folderPath) { var ds = new CaptureDocumentService(); var folder = ds.GetFolder(sessionId, null, folderId); var files = new List<string>(); if (folder.Documents != null) { foreach (var doc in folder.Documents) { files.Add(SaveSourceFile(sessionId, doc.Id, folderPath)); } } return files.ToArray<string>(); } /// <summary> /// OPMT can only send email from the file system from the specific tenant's generated documents path. The email activity will /// add that path when trying to get the file, so this function will save to that folder, then return only file names instead of /// full paths. That way the return value can be used directly in the email activity's attachment field. /// </summary> /// <param name="sessionId"></param> /// <param name="folderId"></param> /// <param name="tenantName"></param> /// <param name="live">True if live, false if dev</param> /// <returns>array with the resulting file names. Suitable for mapping to a dynamic complex variable with one string column, /// and mapping to the attachment field of an email activity.</returns> public string[] SaveSourceFilesOpmt(string sessionId, string folderId, string tenantName, bool live) { var ds = new CaptureDocumentService(); var folder = ds.GetFolder(sessionId, null, folderId); var files = new List<string>(); string tenant = tenantName + "_" + (live ? "live" : "dev"); string folderPath = @"C:\ProgramData\Kofax\TotalAgility\Tenants\" + tenant + @"\Generated Documents\"; if (folder.Documents != null) { foreach (var doc in folder.Documents) { string filePath = SaveSourceFile(sessionId, doc.Id, folderPath); var file = new FileInfo(filePath); // just add the file name within the OPMT generated docs folder for the given tenant and "liveness" files.Add(file.Name); } } return files.ToArray<string>(); } } }
This is sample code provided as-is. A package containing a test process (EmailWithOriginalFilename) is attached below as a convenience, however this is still just a sample to demonstrate functionality. You should only use the code if you understand it and have the ability to maintain it if needed.
KTA Package: EmailWithOriginalFilename.zip
Level of Complexity
High
Applies to
Product | Version | Build | Environment | Hardware |
---|---|---|---|---|
Kofax TotalAgility | v7.x |
References
Article # 3034969