Transflo Synergize Integration API
Explorer has an integration scheme that works from either a Windows desktop or a web browser (or control). It provides secure, reliable access to data in a Synergize repository. This guide is intended to help developers of third-party systems (like transportation logistics management systems) write the code that is needed to ensure the security and reliability of the integration.
There are two types of integration: Desktop-based and Web-based. First, to understand how Synergize Integration Configurations are created, see Configure a Synergize Explorer Integration
The information in a Synergize repository is protected so that only trusted agents can request data and the actual signed-in users are identified so they see only the documents that they are allowed to see. To accomplish this, there are three configurable elements to integration:
-
Server identity (where the Explorer application is set up and identified with a base URL)
-
Customer ID (which company is making the request)
-
Encryption key (the private key that is paired with the customer ID to determine whether the request is coming from a trusted source)
A URL for Synergize Explorer integration is created using a single API call. Behind the scenes, the following occurs:
-
Starting with the base URL
-
Encrypting and appending the query portion of the URL
-
Digitally signing the URL
-
Returning the fully-encrypted and signed URL
For security reasons, the URL can be used only once, to execute the initial search through the Synergize repository. A second attempt to use the URL (for example, by a copied and pasted URL or refreshing the browser) will not be allowed. However, you can refresh the data in an existing window, by coding a conditional check to see if the window still exists and sending it a command.
As a prerequisite, you must use .NET Full, until we support .NET Core alone.
There are two integration types; one builds on the other. Once you have configured the web-to-web configuration, you can build on that to accomplish the Windows desktop to web integration.
1. Basic JavaScript integration (all implementations): Web to Web
2. Windows integration (extra steps): Windows Desktop to Web
This form of integration uses Javascript.
The following DLLs are provided by FTP as part of the integration:
-
SynergizeExplorer.Integration.dll
-
Newtonsoft.json.dll
To ensure that you're using the correct binary version of the integration DLL, we provide an SHA 256 hash as well:
-
SHA256.txt
On the Microdea FTP site, these DLLs are in the Synergize Explorer Integration folder. As an integrator, you can get access to this FTP site from your Microdea liaison.
These DLLs contain the Build.IntegrationUrl method, which needs to be referenced by your .NET application or bridged from another environment. Usually this means you just drop the DLLs into your application's bin directory.
Call the Integration Code
When you want to call the code from a web app, you can control how the call is made. This code calls a new browser tab or window.
1 |
using SynergizeExplorer.Integration |
2 |
|
3 |
class SynergizeController { |
4 |
|
5 |
public SynergizeController() { |
6 |
_builder = new Build(); |
7 |
} |
8 |
|
9 |
private static IntegrationModel WonderlandModelBlueBird => new IntegrationModel { |
10 |
Configuration = "Shipping", |
11 |
Query = new Dictionary < string, object > { |
12 |
{ |
13 |
"CompanyName", |
14 |
"Blue Bird" |
15 |
} |
16 |
} |
17 |
}; |
18 |
|
19 |
[HttpGet("/synergizeIntegration")] |
20 |
public ActionResult < string > GetUrl() { |
21 |
var customerId = "5f2bd9b094b7489c9896f356900cfb6a"; |
22 |
var encryptionKey = "pCmMK5gCaLDI5k5me0shKXFXPPUBtA5LFH0y9qp6xs0="; |
23 |
var urlui = "https://yourAppBase.fake.com/SynergizeExplorer/ExplorerUI/"; |
24 |
|
25 |
var url = _builder.IntegrationUrl(urlui, WonderlandModelBlueBird, customerId, encryptionKey); |
26 |
return Ok(url); |
27 |
} |
28 |
} |
If the window has already been launched previously and is still open, you only want to refresh the data and not relaunch the entire window. Use the configuration name to specify the exact window you want to update.
You can also address any window you want to close by using the configuration name. For example, on the client side:
window.open('https://ses.azurefd.net/SynergizeExplorer/ExplorerUI/#/integration?encryption......', configName)
Please place the SynergizeExplorer.Integration.dll and Newtonsoft.Json.dll, as described in Web to Web.
Next, you need the SynergizeFiles folder copied into the same directory as the two Web to Web DLLs (this folder contains all the files necessary to launch the Chrome window for desktop integration only).
On the Microdea FTP site, these DLLs and the SynergizeFiles folder are in the Synergize Explorer Integration folder.
As an integrator, you can get access to this FTP site from your TRANSFLO® liaison.
Using the Windows Integration API
For each screen or module in your system that presents different information, you may need a different configuration. Do the following to use the API successfully:
-
Initialize by specifying a user.
-
Implement error handling.
-
Construct an IntegrationModel object and call the following method from the API which returns a valid URL in a string:
SynergizeWindowsIntegration.ShowDocuments(string baseURL, IntegrationModel model, string customerID, string encryptionKey)
-
Use Close, to clean up resources and shut down all integration windows. (You can also close specific integration windows with the CloseScenario method.)
The following table refers to the code example included below.
# |
Method |
Parameter Name |
Notes |
---|---|---|---|
1. |
Initialize |
options (WindowsSessionOptions) |
Username: pass the Synergize username of the user that is logged in to your third-party system. Ideally you are using Windows Authentication on your system and in Synergize, so that the username can be the same. If you decide to pass only the base username, you can still set up Synergize to prepend a domain to make the username match your Active Directory or Windows user list. See Single Sign-On (SSO) information in Setting Security Model for Deployment to see how to prepend the domain. |
2. |
OnError |
ErrorHandler |
Standard error handler structure with a sender and event arguments that include message and data. |
3. |
ShowDocuments |
baseURL (string) |
A string that must match the Base URL value from the Integration Configuration screen, For example: http://writer.dev.local/SynergizeEnterpriseServer/SynergizeExplorerUI is a valid base URL. |
model (IntegrationModel) |
A data class that contains the following attributes: Configuration: pass the name of a configuration that you want to associate with your third-party system. It must match the name of a Configuration that has been added with the Synergize Explorer Integration Configuration interface. Query: pass a structure (Dictionary) of key-value pairs. The key must be the same as the configuration-specified field name for the "external" system, in other words: your system. The value can be any object supported by the Synergize repository (string, integer, date, boolean, and others), but the data type must match the Synergize field that is mapped to the external field. This set of pairs is used in an SQL Query, ANDed together to get a result set. |
||
customerID (string) |
Pass the string from the configuration integration connection info screen. This identifies your company. |
||
encryptionKey (string) |
Pass the string from the configuration integration connection info screen. This is a secret key known only to the administrator that configured the Synergize integration. If you suspect a security breach related to the integration, you should regenerate this key, using the Synergize Integration Configuration connection info panel and change it in your integrating code. |
||
4. |
Close |
|
Clean up resources and close all integration windows. |
Desktop to Web Example
Here is a code snippet that integrates a mock TMS. The desktop to web integration launches a specific browser window, and thus has a requirement for Chrome.
-
You need to pass an Integration Model and ensure your settings for base URL, Customer ID, and Encryption Key match the configuration settings.
-
The key-value pairs are ANDed to form a valid SQL query in the repository database.
1 |
using SynergizeExplorer.Integration; // use DLL |
2 |
|
3 |
const string customerId = "5f2bd9b094b7489c9896f356900cfb6a"; |
4 |
const string encryptionKey = "pCmMK5gCaLDI5k5me0shKXFXPPUBtA5LFH0y9qp6xs0="; |
5 |
const string baseUrl = "https://yourAppBase.fake.com/"; |
6 |
|
7 |
// username is the user that will be used to access the Synergize documents |
8 |
// A null value means the Default username configured on the Integration settings will be used. |
9 |
// In this case configuring the default username is required. |
10 |
string username = null; |
11 |
|
12 |
// Uncomment next line if you would like to use the windows user running your application |
13 |
// username = System.Security.Principal.WindowsIdentity.GetCurrent().Name; |
14 |
|
15 |
// If you need Synergize to run in the context of another user then calculate the username variable accordingly |
16 |
|
17 |
// Call Initialize on startup |
18 |
// Initialize can only be called once. If called another time it will throw an exception. |
19 |
var options = new WindowsSessionOptions { UserName = string.IsNullOrEmpty(username) ? null : username}; |
20 |
SynergizeWindowsIntegration.Initialize(options); |
21 |
|
22 |
// Define an error handling function to handle error events |
23 |
SynergizeWindowsIntegration.OnError += ErrorHandler; |
24 |
|
25 |
private static void ErrorHandler(object sender, ErrorEventArgs e) |
26 |
{ |
27 |
var message = e.Message; |
28 |
var data = e.Data; |
29 |
// custom code to display message and log error data and/or message |
30 |
} |
31 |
|
32 |
// To run a search for: Configuration="Shipping", Company="Blue Bird" |
33 |
var blueBirdSearch = new IntegrationModel |
34 |
{ |
35 |
Configuration = "Shipping", |
36 |
Query = new Dictionary<string, object> { { "CompanyName", "Blue Bird" } } |
37 |
}; |
38 |
SynergizeWindowsIntegration.ShowDocuments(baseUrl, blueBirdSearch, customerId, encryptionKey); |
39 |
|
40 |
// Running another search with the same configuration executes the search in the same Chrome window |
41 |
// To run a search for: Configuration="Shipping", Company="ABC Trucking" |
42 |
var truckingSearch = new IntegrationModel |
43 |
{ |
44 |
Configuration = "Shipping", |
45 |
Query = new Dictionary<string, object> { { "CompanyName", "ABC Trucking" } } |
46 |
}; |
47 |
SynergizeWindowsIntegration.ShowDocuments(baseUrl, truckingSearch, customerId, encryptionKey); |
48 |
|
49 |
|
50 |
// Running another search with another configuration launches a new Chrome window |
51 |
// To run a search for: Configuration="RC", Email="someone@myCompany.com" |
52 |
var emailSearch = new IntegrationModel |
53 |
{ |
54 |
Configuration = "RC", |
55 |
Query = new Dictionary<string, object> { { "Email", "someone@myCompany.com" } } |
56 |
}; |
57 |
SynergizeWindowsIntegration.ShowDocuments(baseUrl, emailSearch, customerId, encryptionKey); |
58 |
|
59 |
// If there is a need to programmatically close the Chrome window associated with a configuration |
60 |
// the following line can be used to close the Chrome window associated with the "Shipping" configuration |
61 |
SynergizeWindowsIntegration.CloseScenario("Shipping"); |
62 |
|
63 |
// Call this line once before shut down. |
64 |
// It will close all Chrome windows associated with any open configuration |
65 |
// It will also release any other resources |
66 |
SynergizeWindowsIntegration.Close(); |
This integration code remembers the location and size of integration browser windows within and across application sessions. Settings are stored per machine, per user, and per integration configuration in JSON format in the following file:
%APPDATA%\Microdea\IntegrationLauncher\IntegrationLauncherSettings.json
Tip: If the integration launcher settings are incorrect for some reason and the user cannot see the Chrome window, try deleting the file and restarting the application.
The integration engine uses an environment variable called SYN_CHROME_EXE to find the location of the Chrome executable. If this variable is not set, the engine tries to find chrome.exe in the %APPDATA% folder as well as Program Files and Program Files (x86) directories.
Common chrome.exe locations:
C:\'Program Files (x86)'\Google\Chrome\Application\chrome.exe
C:\'Program Files'\Google\Chrome\Application\chrome.exe
C:\Users\<UserName>\AppData\Local\Google\Chrome\Application\chrome.exe
If you have created the following configuration, you would need to ensure that you used values in your call that matched:
-
The Base URL, Customer ID, and Encryption Key, as specified on the Connection Info page
-
Configuration Name: ARDOCS_TMWSuite
-
Your Dictionary of key-value pairs with just one entry, the key called ord_number (the External name in the Field mapping table). (The value for ord_number would come from, for example, the currently selected record in the screen that is calling the integration code.)
-
In a repository that has been enabled for views, you have an additional field to define the default view.
Note that you can select available views in the repository, but a User's access to particular views is still honored by the system.
In other words, the user may not have access to the default view but would still be able to select the repository views they did have access to.
For your convenience, we provide the following call to confirm that the integration model is actually being derived properly. Call the method to return an IntegrationModel and compare it to the one you instantiated before.
Given the same encrypted URL, customer ID, and encryption key, the models should be equal.
-
return a deserialized IntegrationModel class :
-
Build.IntegrationModel(string url, string customerId, string encryptionKey)
-
You can use the Microdea Common DLL as a streamlined interface to our Synergize SOAP interface. We have simplified the most common interactions with the Synergize repository to help you integrate our function with your products.
-
You make the calls using C# or VB.NET in the .NET framework.
-
We currently support .NET Framework Version 3.5 and later.
-
Other languages can be supported with direct SOAP calls. (Discuss this with your TRANSFLO® representative.)
To integrate the calls into your code, you can use this guide to see what the calls expect and what they return.
Assumptions
There are some assumptions which should help you understand how the calls behave. All calls are made within the context of a connection. You connect to the web service and then make requests to that service.
Establish a connection to the base web service, by populating a WebService object with the following items:
-
repository
-
username
-
password
and optionally
-
server
-
KeepAlive flag
Once the WebService object is ready, call its connect method. Interactions with the Synergize Common DLL usually involve setting up an object and passing it to a call. The response is often a Collection, which you can access element by element.
For most calls, an error message must be passed by reference. The call returns a boolean.
-
If false, an error occurred and the error message is populated with a string describing the actual error.
-
If the call is successful (returning true), the referenced error message is empty.
Download the Synergize DLL
You can download the Synergize DLL from our FTP site. To access the site, you need a developer username and password, which is separate from your customer username and password.
1. Go to the URL: http://ftp.microdea.com
-
Username: <to_be_provided_by_Microdea>
-
Password: <to_be_provided_by_Microdea>
2. Download the following file.
-
SDK\SynergizeDLL.zip
The zip file contains the following:
-
Microdea Common\SynUtilities.dll
-
Microdea Common\Microdea.Common v2.3.dll
-
NetSetDeployment\NETSetDeployment.exe
3. Install NETSetDeployment.exe and run as an “admin” in your environment to test your connection to the deployment URL.
The deployment URL should be in the Windows registry, from which NETSetDeployment reads it.
Copy the following files into your environment.
-
Microdea Common\SynUtilities.dll
-
Microdea Common\Microdea.Common v2.3.dll
Connect to the Web Service
First, prepare the namespace so you don't have to fully-qualify later references:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Microdea.Common;
using Microdea.Synergize;
Next, define the items that you'll use when you call the connect method:
private const string Repository = "TESTREPOSITORY";
private const string User = "username"; // or "DOMAIN\username";
private const string UserPassword = "password";
Finally, set up a using nest with the SynergizeWebService:
using (
var webService = new Microdea.Synergize.SynergizeWebService
{
Username = User,
Password =UserPassword,
Server = string.Empty,
Repository = Repository,
KeepAlive = true
})
Finally, connect using the web service's connect method:
if (!webService.Connect(ref errorMessage))
{
// Error handling code
}
Use your own error handling code. All further examples are assumed to run within the context of the using clause set up in this example.
Typical Scenarios
The most common Synergize functions used in integrations are:
-
Save Document
-
Search Document
-
Update Document Properties
-
Get Document Image
-
Workflow Process
Save a document
Initialize a Synergize document object.
var myDocument = new SynergizeDocument();
Populate the attributes of the document, including the file that will be known as the document image.
newDocument.SetValue("In_DocName", "My New Document", DocumentFieldType.Synergize);
newDocument.DocumentType = "Undefined";
newDocument.SetValue("TextField", "Some text", DocumentFieldType.Synergize);
newDocument.Filename = FileToSave;
Call the SaveDocument method and process the results. On success you get the new document's ID. On error you get an error message.
if (webService.SaveDocument(myDocument, null, ref errorMessage))
{
// After saving document successfully in the repository, perform additional processing
}
else
{
// Error handling code
}
Search for a Document
In this example, the search is done for a document by its ID. The variable DocIdToUpdate is a string constant, initialized elsewhere.
var query = new object[] { "In_DocID", "=", string.Format("\"{0}\"", DocIdToUpdate)};
Note how the substitution is done, inserting DocIdToUpdate into the object, which is a series of tokens making up the full query. A query can have many formats and supports multiple boolean logic statements.
Query Formats
Using the Synergize Common DLL, you can format your query strings in the several standard ways. Note that each part of the string is an element in the array that is assembled to contain the query.
You can nest logical expressions within parentheses and use boolean logical operators like equal, greater than, less than, and not equal. A typical query might look like this:
((Field1 = "xxxx") OR (Field1 = "yyyy")) AND (CustomerNumber <> 1500)
Each part of the expression is inserted into an array, so before the call to execute the above query, you'd create the query object like this:
var query = new object[] { "(", "(", "Field1", "=", "\"xxxx\"", ")", "OR", "(", "Field1", "=", "\"yyyy\"", ")", ")", "AND", "(", "CustomerNumber", "<>", 1500, ")"};
If you want to use a variable from elsewhere in your code to pass through in the query, you would use the following syntax for the element:
string.Format("\"{0}\"", VariableName)
After you have assembled the query object, you can call the FindDocuments method. It takes the query, search options which should be set to null, a result set cap, and a reference to an error message string. In the example below, the result set is limited to one. Once again, process the results, either an error or a collection.
Note that in the case of success (as in the example below), the collection could include multiple documents, but commonly you'd use the first element (0) of the collection. Also note that it is important to cast the element of the collection to an actual SynergizeDocument, before further processing.
var documents = webService.FindDocuments(query, null, 1, ref errorMessage);
if (documents == null)
{
//error case - use the ref errorMessage parameter to determine the reason
}
else
{
if (!documents.Any())
{
//no documents found
}
else
{
if (string.IsNullOrEmpty())
{
//documents collection has documents within record limit
}
else
{
//documents collection has documents but more documents are available
}
}
}
Update Document Properties
You can use a document identifier to access a document in the repository and update its properties (or metadata). You can access any existing property by name and set its value.
In this example, the TextField property is set to 345 and then the UpdateDocumentProperties method is called. Again, the result is either success or error.
myDocument.SetValue("TextField", "345", DocumentFieldType.Synergize);
if (webService.UpdateDocumentProperties(myDocument, ref errorMessage))
{
// After updating document properties successfully in the repostitory, perform additional processing
}
else
{
// Error handling code
}
}
Get Image
After you have a document identifier, you can use it to access the document image. A document image is the actual file stored in the repository, separate from the properties (metadata) describing it. Use the document object to get the image.
document.SetValue("In_DocID", DocIdToOpen);
Set up options that are used to make sure the document image is presented properly to your users. The options object is a dictionary of key value pairs, The pairs can include file format, redactions, and visual annotations.
Remember, a file can be in almost any format, including video, so some options are not applicable to some file formats, and only some file formats can be converted to others.
A common way to get images is to convert the stored TIFF image to a PDF, with all redactions and annotations turned on, as in the following example.
var options = new Dictionary<String, Object>();
options.Add("ShowRedactions", 1);
options.Add("ShowAnnotations", 1);
options.Add("ImageFormat", "PDF");
var filePath = webService.GetDocument(myDocument, options, "", ref errorMessage);
if (!string.IsNullOrEmpty(errorMessage))
{
// Error handling code
}
else
{
// After getting the image successfully in the repostitory, perform additional processing
// IMPORTANT: you must the delete image file as part of this processing
}
Workflow Process
Processing a document through a workflow involves changing a property that represents the queue that a document is sitting in. In this way, you are taking advantage of the "state machine" that is Synergize Workflow.
-
As before, the first step is to acquire a Synergize document object.
-
Next, use that document object to call the process workflow method, passing the document, a workflow scenario identifier, and a named queue into which the document should be moved.
if (webService.ProcessWorkflow(myDocument, WorkflowScenarioId, WorkflowDestinationQueue, ref errorMessage))
{
// After moving the document to the correct queue, perform additional processing
}
else
{
// Error Handling
}
The encryption of a password is a fundamental security precaution that can be used, when calling Synergize web services. You can also encrypt a username. To leverage the Synergize utility that offers encryption so that Synergize can decrypt the information after the call is made, do the following:
-
Get encryption key from deployment and cache it. Code should look like the following (VB.NET):
Private Shared Function GetEncryptionKey() As String
-
Using mgmt as SynergizeWebAdmin.DeploymentMgmt = GetConnection() ' => SynergizeWebAdmin is a wrapper created by VS; GetConnection - function that uses deployment url and returns SynergizeWebAdmin.DeploymentMgmt object
Dim errorMessage As String = Nothing
Dim info As SynergizeWebAdmin.DeploymentEncryptionInfo = Nothing
If mgmt.GetEncryptionInfo(info, errorMessage) <> 0 Then
Throw New ApplicationException("error getting encryption info - " & errorMessage)
End If
Return info.PublicKey
End Using
End Function
2. Using SynUtilities DLL, encrypt the username and password using key from Step 1:
Dim encryption = New SynUtilities.DeploymentEncryption(publicKey)
Dim symmetricKey As String = Nothing
Dim encrypted() As String = encryption.Encrypt(New String() {userName, userPassword}, symmetricKey)
3. Create headers for the GetServerToken call (note that in this example the username is not encrypted and the password is encrypted):
Dim encHeader=new EncryptionHeader() With {.PublicKey= symmetricKey}
Dim header=new AuthHeader() With {.WebUserName=encrypted(0), .WebUserPassword=encrypted(1), ...}
4. Use these headers in GetServerToken call.
To set up TMW Web Products to work with the original Synergize QuickLink, you must identify Microdea as your imaging service vendor and provide connection information.
-
Go to Menu > Configuration > Imaging Settings.
The Imaging Settings page appears.
-
In the leftmost drop-down list, select the module for which you want to define imaging settings. You can select Carrier, Customer, or Driver.
-
In the rightmost drop-down list, select Microdea. The Imaging Settings page refreshes to show fields for the Microdea imaging service.
-
In the Microdea Imaging Configuration section, make the required entries about your Microdea imaging service. Fields with an asterisk (*) are required.
-
Microdea Web Services URL*: Web address of your Microdea imaging system.
-
Web Services Timeout: Number of seconds before the connection to the Microdea imaging system will be broken when no response is received.
-
Reference Column*: Name of the column your Microdea imaging system uses to link images to another service The value used for your basic Microdea imaging setup must be used for TMW Web Products.
-
Server*: Name of the host server used by your imaging web service.
-
Repository*: Location on the host server where images are stored by your imaging web service.
-
Document View*: Layout file name specified here must match the document view specified for your imaging web service. If you do not use document views with your basic Microdea imaging system, you may leave this field blank. However, if you use a document view with Microdea and you leave this field blank, errors will occur when a user attempts to view a paperwork image.
-
Web User Name*: User ID associated with your imaging web service.
-
Web User Password*: Password associated with the user ID specified in the Web User Name field.
-
DocumentSearchType: Document type to match in TMWSuite.
-
Code: Matches documents by document type abbreviation.
-
Description: Matches documents by document type name.
-
-
-
In the File Upload Settings section, specify an upload method. You can allow users to upload files from a directory on a computer or server.
-
Click Save Configuration in the top right corner of the page.
-
If the settings are correct, a message appears indicating that your settings were saved.
-
If one or more settings is incorrect, a message appears advising you to check your settings.
-
-
Make any corrections and click Save Configuration, to retest your entries.
-
To test the connection with the information entered, click Test Connection. If the connection works, a message appears indicating that the test was successful.
In December 2023, Release 15.3.1 introduces the following new TRANSFLO.BatchStatusWorkflow API endpoints:
- PUT GetNextAvailableBatch
- PUT SetBatchProcessingStatus
- PUT UpdateBatchXML
- PUT UpdateBatchXMLToFinal
- PUT MoveBatchToNextStep
- PUT MoveBatchToFinalStep
- GET GetBatchByConfirmationNumber
The following example shows how you can use these new REST API calls with document batches in your integrated Synergize environment:
-
In a web browser, navigate to your test or production API instance where you have installed your local Synergize API endpoints as seen through Swagger (you can also use POSTMAN or another REST API endpoint tool):
Example:
cust123.transflo.ws/transflo.batchstatusworkflow/swagger/index.html
-
Select a server in the Servers field and then click Authorize.
-
Enter your API access token key and click the Authorize button.
-
Click Close.
Tip: In some environments, you might need to click Logout to establish a new unique secure connection with your new access token.
-
Under Batches, expand the API call you want to use.
-
Enter your parameters. In this example, you can enter parameters to the GetBatchByConfirmationNumber REST API call to get batch information in JSON format for the specified confirmationNumber string.
-
In this example, you enter a statusID string, ApplicationInstanceID integer, and leave the default ContextCorrelationID string. Click Execute.
-
Under Responses, you should see a successful server response Code of 200.