File Translation Service
FileTranslationService submits batches of files to a translation provider asynchronously. When the run completes, Vault invokes a post-processing event handler that saves the translated output in Vault. For example, the translated output may be saved as a new document, a new version, a rendition, or an attachment.
FileTranslationService is typically invoked from a user action, entry action, workflow job step, or agent tool.
Key Functionality
Section link for Key FunctionalityA translation run has three components:
- Initiation: Your code assembles a
FileTranslationBatchRequest. This includes oneFileTranslationInputper file, a connection name identifying the translation provider, an event handler API name, and an optionalFileTranslationParametersinstance to hold the context your handler will need. CallingbatchTranslateFilesqueues the job. - Translation: The job runtime submits each file to the provider identified by the connection record and polls for results.
- Post-processing: When all files have completed or failed, Vault invokes the
FileTranslationEventHandleryou specified, which saves the translated output in Vault and has access to the original collection of parameters for any additional context it needs. For example, the translated output may be saved as a new document, a new version, a rendition, or an attachment.
Submitting a Translation Batch
Section link for Submitting a Translation BatchThe following example demonstrates locating FileTranslationService via ServiceLocator, building one FileTranslationInput per file, then building and executing the FileTranslationBatchRequest.
FileTranslationService translationService = ServiceLocator.locate(FileTranslationService.class);
// Build the input for a single file
FileTranslationInput input = translationService.newFileTranslationInputBuilder()
.withSourceFile(sourceFileReference)
.withSourceLanguageCode("en") // optional; omit to let the provider detect it
.withTargetLanguageCode("es")
.build();
// Build the batch request
FileTranslationBatchRequest request = translationService.newFileTranslationBatchRequestBuilder()
.withFileTranslationInputs(VaultCollections.asList(input))
.withConnectionName("my_provider__c") // api_name__sys of the Translation Provider connection record
.withEventHandlerApiName("my_translation_handler__c")
.build();
// Submit the batch
translationService.batchTranslateFiles(request)
.onErrors(errors -> {
for (FileTranslationSubmissionError error : errors) {
// Log or handle error here
}
})
.execute();batchTranslateFiles returns a FileTranslationBatchOperation that exposes three strategies for pre-queue validation failures:
ignoreErrors(): Submit valid rows; skip invalid rows silently.onErrors+ignoreErrors(): Handle row-level failures, then submit valid rows.rollbackOnErrors(): Fail the entire batch if any row is invalid; nothing is queued.
FileTranslationErrorType describes the possible pre-queue validation failures:
SOURCE_FILE_NOT_READABLEPROVIDER_NOT_FOUNDPROVIDER_NOT_ACTIVEEVENT_HANDLER_NOT_FOUNDSOURCE_FORMAT_UNSUPPORTEDTARGET_LANGUAGE_UNSUPPORTED
File Translation Parameters
Section link for File Translation ParametersFileTranslationParameters represents a keyed, serializable collection of parameters attached to the batch request. Vault carries it across the asynchronous boundary and makes it available to the event handler via FileTranslationEventHandlerContext. Use it to pass any context your handler needs, such as source document IDs, configuration names, or notification flags.
Set scalar values using FileTranslationParameterValueType constants:
FileTranslationParameters parameters = translationService.newFileTranslationParametersBuilder()
.appendValue("config_name", "my_translation_config__c")
.appendValue("send_notification", true)
.build();For structured data, implement FileTranslationParameterValue in a @UserDefinedClass. All fields must use scalars or collections of scalars to ensure serialization across the asynchronous boundary.
@UserDefinedClassInfo()
public class MyTranslationContext implements FileTranslationParameterValue {
private String sourceDocumentVersionId;
private String targetLanguageCode;
// getters and setters
}Retrieve values in the event handler using FileTranslationEventHandlerContext#getParameter:
// Scalar value
String configName = context.getParameter("config_name", FileTranslationParameterValueType.STRING);
// Custom type
MyTranslationContext ctx = context.getParameter("my_context", MyTranslationContext.class);Implementing a File Translation Event Handler
Section link for Implementing a File Translation Event HandlerVault invokes FileTranslationEventHandler when a translation run completes. It owns all post-processing: storing the translated files, updating records, and notifying users.
Implement the FileTranslationEventHandler interface and annotate the class with @FileTranslationEventHandlerInfo. The apiName attribute must be unique within your Vault and follow standard naming conventions (__c for custom handlers).
The interface requires two methods, both receiving a FileTranslationEventHandlerContext:
onCompleteWithSuccess: Vault calls this method only when every input in the batch succeeded. Usecontext.getResults()to retrieve eachFileTranslationResultSuccess.onCompleteWithError: Vault calls this method when any input failed, even if other inputs in the same batch succeeded. Use bothcontext.getResults()for successes andcontext.getErrors()for failures.
import com.veeva.vault.sdk.api.translation.*;
@FileTranslationEventHandlerInfo(apiName = "my_translation_handler__c")
public class MyTranslationHandler implements FileTranslationEventHandler {
@Override
public void onCompleteWithSuccess(FileTranslationEventHandlerContext context) {
for (FileTranslationResultSuccess result : context.getResults()) {
// Retrieve the successfully translated file
FileReference translatedFile = result.getFileReference();
}
}
@Override
public void onCompleteWithError(FileTranslationEventHandlerContext context) {
for (FileTranslationResultSuccess result : context.getResults()) {
// Retrieve the successfully translated file
FileReference translatedFile = result.getFileReference();
}
for (FileTranslationResultError result : context.getErrors()) {
// Log or handle provider-level error here
}
}
}FileTranslationProviderErrorType describes possible provider-side failures on a FileTranslationResultError:
INVALID_REQUESTAUTHENTICATION_FAILEDPROVIDER_UNAVAILABLEPROVIDER_ERRORUNEXPECTED_ERROR
Document Translation Event Handlers
Section link for Document Translation Event HandlersInstead of implementing your own FileTranslationEventHandler, you can use one of the two document translation event handlers by passing its API name constant to withEventHandlerApiName:
DocumentCreationHandlerParameters.API_NAME(document_creation__sys): Creates a new translated document per successfully translated file, copying fields from a source document version and linking each translation back to it.DocumentUpdateHandlerParameters.API_NAME(document_update__sys): Creates a new version of an existing target document from the translated content. Only appropriate when a single target language is selected and the batch has exactly one input.
Each platform handler requires its own collection of parameters, built via FileTranslationService and attached to FileTranslationParameters under the handler's PARAMETER_NAME. See the Doctranslationsconfig component type for information about how to configure field copy and relationship behavior.
Example: Using a Document Translation Event Handler
Section link for Example: Using a Document Translation Event HandlerThe following example builds a translation request using the document_creation__sys platform handler, which creates a new translated document for each successfully translated file.
FileTranslationService translationService = ServiceLocator.locate(FileTranslationService.class);
// Build the platform handler parameters
DocumentCreationHandlerParameters handlerParameters = translationService
.newDocumentCreationHandlerParametersBuilder()
.withInstanceId("1000443")
.withSourceDocumentId("1502")
.withSourceMajorVersion("1")
.withSourceMinorVersion("0")
.withTargetLanguageCodes(VaultCollections.asList("fr", "de"))
.withNotifyOnCompletion(true)
.build();
// Attach the handler parameters to the batch parameters collection
FileTranslationParameters parameters = translationService.newFileTranslationParametersBuilder()
.appendValue(DocumentCreationHandlerParameters.PARAMETER_NAME, handlerParameters)
.build();
// Build the input
FileTranslationInput input = translationService.newFileTranslationInputBuilder()
.withSourceFile(sourceFileReference)
.withTargetLanguageCode("es")
.build();
// Build and submit the batch
FileTranslationBatchRequest request = translationService.newFileTranslationBatchRequestBuilder()
.withFileTranslationInputs(VaultCollections.asList(input))
.withConnectionName("deepl")
.withEventHandlerApiName(DocumentCreationHandlerParameters.API_NAME)
.withParameters(parameters)
.build();
translationService.batchTranslateFiles(request)
.onErrors(errors -> {
for (FileTranslationSubmissionError error : errors) {
// Log or handle error here
}
})
.execute();See DocumentCreationHandlerParametersDocumentUpdateHandlerParameters