Using the Cloudwords Open API in Java

The Cloudwords API allows you to easily create Cloudwords projects with the content you need translated. This tutorial will illustrate just how simple it is to get your source content into Cloudwords, check its progress during the translation process, and retrieve the translations once delivered by the vendor.

For this tutorial, you will need:

1. A Cloudwords sandbox account. Don't have one? Create one now.
2. The API Access Key for your account. Learn how to get it here.
3. The Java SDK makes it super simple to integrate with Cloudwords using Java.

You can download the code for this tutorial here: Tutorial.java

//Include the Cloudwords Java SDK
import com.cloudwords.api.client.*;
import com.cloudwords.api.client.exception.*;
import com.cloudwords.api.client.resources.*;
import java.io.*;
import org.apache.commons.compress.utils.IOUtils;

public class Tutorial {
    
    public static void main(String[] args) throws CloudwordsClientException, IOException {
        final String BASE_API_URL = "https://api-sandbox.cloudwords.com";
        final String API_VERSION = "1.15";
        final String API_KEY = "INSERT_YOUR_API_KEY_HERE";
        
        CloudwordsCustomerAPI customerClient = new CloudwordsCustomerClient(BASE_API_URL, API_VERSION, API_KEY);

That's it! Now we're ready to start using the Java SDK for Cloudwords to easily access your Cloudwords account. Let's start by getting some information about our Cloudwords account, such as available source languages, target languages, and departments. We can use these values to display options to the user for selection when creating the project.

        List<Language> sourceLanguages = customerClient.getSourceLanguages();
        System.out.println("Source Languages");
        for (Language sl : sourceLanguages) {
            System.out.println(sl.getDisplay() + ": " + sl.getLanguageCode());
        }

        List<Language> targetLanguages = customerClient.getTargetLanguages();
        System.out.println("Target Languages");
        for (Language tl : targetLanguages) {
            System.out.println(tl.getDisplay() + ": " + tl.getLanguageCode());
        }
        
        List<Department> depts = customerClient.getDepartments();
        System.out.println("Customer Departments");
        for (Department d : depts) {
            System.out.println(d);
        }

Now that we have some values that the user can select from, let's create the project in Cloudwords. Note that if the user's Cloudwords account has a non-empty list of departments returned, then a department is required when creating the project. If you just created a Sandbox account, you may not have any departments setup yet.

        Project project = new Project();
        
        // if Departments have been enabled then a Department must also be specified:
        if (depts.size() > 0) {
            project.setDepartment(depts.get(0));
        }

        project.setName("Tutorial Demo Project");
        //we can use the language code in a new Language object
        project.setSourceLanguage(new Language("en-us"));
        
        List<Language> projectTargetLanguages = new ArrayList<Language>();
        //alternatively, we can use languages directly from our returned list
        projectTargetLanguages.add(targetLanguages.get(4));
        projectTargetLanguages.add(targetLanguages.get(9));
        projectTargetLanguages.add(targetLanguages.get(19));
        project.setTargetLanguages(projectTargetLanguages);
        
        //The project content type identifies the originating system of the project in Cloudwords
        project.setProjectContentType("MyIntegration");
        
        //this stops the user from changing the source and target languages in Cloudwords, 
        //as well as prevents them from changing the source files we will upload. We also
        //want to prevent the user from cloning this project in Cloudwords.
        Map<String, Boolean> uiFeatures = new HashMap<String, Boolean>();
        uiFeatures.put("change_source_language", Boolean.FALSE);
        uiFeatures.put("change_target_languages", Boolean.FALSE);
        uiFeatures.put("change_source_material", Boolean.FALSE);
        uiFeatures.put("clone_project", Boolean.FALSE);
        project.setUiFeatures(uiFeatures);

        Project createdProject = customerClient.createProject(project);
        Integer projectId = createdProject.getId();

At this point, we have created the project stub in Cloudwords. We have specified the name, project content type, source language, target languages, and the assigned department for the project. There are lots of additional attributes of the project that an integration can populate, but are all optional. See Create Project for more details.

Now let's add some content to translate. We will upload a couple of files from a sample site.

        SourceDocument indexDoc = customerClient.addSourceDocument(projectId, new File("index.html"));
        SourceDocument aboutDoc = customerClient.addSourceDocument(projectId, new File("about.html"));
        //keep track of sourceDocumentId's to match up with translations later on
        System.out.println("index.html sourceDocumentId: " + indexDoc.getId());
        System.out.println("about.html sourceDocumentId: " + aboutDoc.getId());

The project now has source uploaded in Cloudwords and the user can now be linked to Cloudwords directly to continue project creation including vendor selection and bidding details, due dates for bidding, translation, and review, as well as workflows. The pattern for the URI to link to Cloudwords is as follows:

Environment Project URI
Sandbox https://app-sandbox.cloudwords.com/cust.htm#project/<project_id>
Production https://app.cloudwords.com/cust.htm#project/<project_id>

In order to be notified of when a translation is delivered by a vendor, we will register a webhook. Alternatively, we could poll our Cloudwords project periodically, checking the status of the project and each target language. But using a webhook is much cleaner and efficient.

        customerClient.createWebhook("deliverable_added", 
                "https://app.mycompany.com/cloudwords/translation_delivered", createdProject);

Whenever a deliverable is added to the project, a message will be POSTed indicating the project and language for which the translation was delivered. This allows an integration to then pull those translations back into the integrating system for review. It's possible that a translation will be delivered multiple times through the revision process within Cloudwords, so we should expect that a message may be sent more than once, and that the integrating system should pull those translations each time. As part of the review process, the user may request changes from the vendor for many reasons. Those reasons range from incorrect translations, misspellings, and inadequate capturing of the message, to translation length causing layout issues. More than one iteration of translation is quite common.

Once a project is closed, no more deliverables can be added.

Imagine we were just notified via the webhook that a vendor has delivered a translation for one of our target languages. Let's now pull down the translated files for that language.

        List<TranslatedDocument> translations = customerClient.getTranslatedDocuments(projectId, new Language("fr"));
            
        for (TranslatedDocument doc : translations) {
            if ("delivered".equals(doc.getStatus().getCode())) {
                CloudwordsFile file = doc.getFile();
                File dirPath = new File(targetLanguages.get(4).getLanguageCode());
                dirPath.mkdirs();
                OutputStream os = new FileOutputStream(new File(dirPath, file.getFilename()));
                InputStream is = customerClient.downloadFileFromMetadata(file);
                File sourceDoc = sourceDocIds.get(doc.getSourceDocumentId());
                System.out.println("Downloading " + targetLanguages.get(4).getDisplay() 
                    + " version of " + sourceDoc.getName());
                //use utility method to download file
                IOUtils.copy(is, os);
                is.close();
                os.close();
            }
        }
    }

That's it! A full round-trip project. First we created the project with a few pieces of information. Then we uploaded our source content to the project. After registering a webhook, we sent the user off to Cloudwords to complete the project creation process. Once translations were delivered by the vendor, we were notified and we then downloaded those translations.