Skip to content

Commit 43bbec3

Browse files
author
Chris Paul
authored
Merge pull request hellosign#40 from HelloFax/issue-39
Add method for updating embedded template merge fields and CC roles
2 parents d0a88f6 + 1175c1a commit 43bbec3

3 files changed

Lines changed: 93 additions & 39 deletions

File tree

src/main/java/com/hellosign/sdk/HelloSignClient.java

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import java.io.File;
2828
import java.lang.reflect.Constructor;
2929
import java.net.HttpURLConnection;
30+
import java.util.List;
31+
import java.util.Map;
3032

33+
import org.json.JSONArray;
3134
import org.json.JSONException;
3235
import org.json.JSONObject;
3336

@@ -50,6 +53,7 @@
5053
import com.hellosign.sdk.resource.support.Signature;
5154
import com.hellosign.sdk.resource.support.SignatureRequestList;
5255
import com.hellosign.sdk.resource.support.TemplateList;
56+
import com.hellosign.sdk.resource.support.types.FieldType;
5357

5458
/**
5559
* You'll need the HelloSignClient to do just about everything, from creating
@@ -123,6 +127,8 @@ public class HelloSignClient {
123127
public static final String CLIENT_ID = "client_id";
124128
public static final String EMBEDDED_TEMPLATE_SKIP_SIGNER_ROLES = "skip_signer_roles";
125129
public static final String EMBEDDED_TEMPLATE_SKIP_SUBJECT_MESSAGE = "skip_subject_message";
130+
public static final String EMBEDDED_TEMPLATE_MERGE_FIELDS = "merge_fields";
131+
public static final String EMBEDDED_TEMPLATE_CC_ROLES = "cc_roles";
126132

127133
private Authentication auth;
128134
private HttpClient httpClient;
@@ -186,7 +192,7 @@ public HelloSignClient(Authentication auth) throws HelloSignException {
186192
/**
187193
* Allows overriding of the authentication mechanism. Used
188194
* mainly for setting an OAuth token/secret.
189-
* @param auth
195+
* @param auth Authentication used for setting the auth method for this client
190196
*/
191197
public void setAuthentication(Authentication auth) {
192198
this.auth = auth;
@@ -617,6 +623,8 @@ public boolean deleteTemplate(String templateId) throws HelloSignException {
617623
* @param clientId String optional ID of the app which is generating this
618624
* new template. Set to null if not used.
619625
* @return String ID of the template to be created
626+
* @throws HelloSignException thrown if there is a problem processing the
627+
* HTTP request
620628
*/
621629
public String updateTemplateFiles(String existingTemplateId, TemplateDraft newTemplate, String clientId)
622630
throws HelloSignException {
@@ -832,11 +840,51 @@ public EmbeddedResponse getEmbeddedTemplateEditUrl(String templateId, boolean sk
832840
*/
833841
public EmbeddedResponse getEmbeddedTemplateEditUrl(String templateId, boolean skipSignerRoles,
834842
boolean skipSubjectMessage, boolean testMode) throws HelloSignException {
843+
return getEmbeddedTemplateEditUrl(templateId, skipSignerRoles, skipSubjectMessage, false, null, null);
844+
}
845+
846+
/**
847+
* Big kahuna method for editing an embedded template. This method allows
848+
* the updating of merge fields and CC roles (both optional parameters).
849+
*
850+
* @param templateId String ID of the signature request to embed
851+
* @param skipSignerRoles true if the edited template should not allow the
852+
* user to modify the template's signer roles. Defaults to false.
853+
* @param skipSubjectMessage true if the edited template should not allow
854+
* the user to modify the template's subject and message. Defaults to
855+
* false.
856+
* @param testMode true if this request is a test request. Useful for
857+
* editing locked templates.
858+
* @param mergeFields These will overwrite the current merge fields for the
859+
* embedded template. To remove all merge fields, pass in an empty Map.
860+
* @param ccRoles These will overwrite the current CC Roles for the embedded
861+
* template. To remove all CC roles, pass in null or an empty List.
862+
* @return EmbeddedResponse
863+
* @throws HelloSignException thrown if there's a problem processing the
864+
* HTTP request or the JSON response.
865+
*/
866+
public EmbeddedResponse getEmbeddedTemplateEditUrl(String templateId, boolean skipSignerRoles,
867+
boolean skipSubjectMessage, boolean testMode, Map<String, FieldType> mergeFields, List<String> ccRoles)
868+
throws HelloSignException {
835869
String url = BASE_URI + EMBEDDED_EDIT_URL_URI + "/" + templateId;
836-
return new EmbeddedResponse(
837-
httpClient.withAuth(auth).withPostField(EMBEDDED_TEMPLATE_SKIP_SIGNER_ROLES, skipSignerRoles)
838-
.withPostField(EMBEDDED_TEMPLATE_SKIP_SUBJECT_MESSAGE, skipSubjectMessage)
839-
.withPostField(AbstractRequest.REQUEST_TEST_MODE, testMode).post(url).asJson());
870+
HttpClient client = httpClient.withAuth(auth)
871+
.withPostField(EMBEDDED_TEMPLATE_SKIP_SIGNER_ROLES, skipSignerRoles)
872+
.withPostField(EMBEDDED_TEMPLATE_SKIP_SUBJECT_MESSAGE, skipSubjectMessage)
873+
.withPostField(AbstractRequest.REQUEST_TEST_MODE, testMode);
874+
String mergeFieldsStr = TemplateDraft.serializeMergeFields(mergeFields);
875+
if (mergeFieldsStr != null) {
876+
client = client.withPostField(EMBEDDED_TEMPLATE_MERGE_FIELDS, mergeFieldsStr);
877+
}
878+
if (ccRoles == null || ccRoles.isEmpty()) {
879+
// Per documentation: https://app.hellosign.com/api/reference#get_embedded_template_edit_url
880+
client = client.withPostField(EMBEDDED_TEMPLATE_CC_ROLES + "[0]", "");
881+
} else {
882+
for (int i = 0; i < ccRoles.size(); i++) {
883+
String cc = ccRoles.get(i);
884+
client = client.withPostField(EMBEDDED_TEMPLATE_CC_ROLES + "[" + i + "]", cc);
885+
}
886+
}
887+
return new EmbeddedResponse(client.post(url).asJson());
840888
}
841889

842890
/**

src/main/java/com/hellosign/sdk/resource/SignatureRequest.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -284,33 +284,27 @@ public Map<String, Serializable> getPostFields() throws HelloSignException {
284284
List<Signer> signerz = getSigners();
285285
for (int i = 0; i < signerz.size(); i++) {
286286
Signer s = signerz.get(i);
287-
288-
// The signers are being ID'd starting at 1, instead of zero.
289-
// This is because the API generates signer IDs for templates
290-
// starting at 1.
291-
// Let's keep this consistent with the API for now.
292-
293-
fields.put(SIGREQ_SIGNERS + "[" + (i + 1) + "][" + SIGREQ_SIGNER_EMAIL + "]", s.getEmail());
294-
fields.put(SIGREQ_SIGNERS + "[" + (i + 1) + "][" + SIGREQ_SIGNER_NAME + "]", s.getNameOrRole());
287+
fields.put(SIGREQ_SIGNERS + "[" + i + "][" + SIGREQ_SIGNER_EMAIL + "]", s.getEmail());
288+
fields.put(SIGREQ_SIGNERS + "[" + i + "][" + SIGREQ_SIGNER_NAME + "]", s.getNameOrRole());
295289
if (getOrderMatters()) {
296-
fields.put(SIGREQ_SIGNERS + "[" + (i + 1) + "][" + SIGREQ_SIGNER_ORDER + "]", i);
290+
fields.put(SIGREQ_SIGNERS + "[" + i + "][" + SIGREQ_SIGNER_ORDER + "]", i);
297291
}
298292
if (s.getAccessCode() != null) {
299-
fields.put(SIGREQ_SIGNERS + "[" + (i + 1) + "][" + SIGREQ_SIGNER_PIN + "]", s.getAccessCode());
293+
fields.put(SIGREQ_SIGNERS + "[" + i + "][" + SIGREQ_SIGNER_PIN + "]", s.getAccessCode());
300294
}
301295
}
302296
List<String> ccz = getCCs();
303297
for (int i = 0; i < ccz.size(); i++) {
304298
String cc = ccz.get(i);
305-
fields.put(SIGREQ_CCS + "[" + (i + 1) + "]", cc);
299+
fields.put(SIGREQ_CCS + "[" + i + "]", cc);
306300
}
307301
JSONArray reqFormFields = new JSONArray(); // Main array for the
308302
// request
309303
boolean hasFormFields = false;
310304
List<Document> docs = getDocuments();
311305
for (int i = 0; i < docs.size(); i++) {
312306
Document d = docs.get(i);
313-
fields.put(SIGREQ_FILES + "[" + (i + 1) + "]", d.getFile());
307+
fields.put(SIGREQ_FILES + "[" + i + "]", d.getFile());
314308
JSONArray docFormFields = new JSONArray();
315309
for (FormField ff : d.getFormFields()) {
316310
hasFormFields = true;

src/main/java/com/hellosign/sdk/resource/TemplateDraft.java

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.Map;
3232

3333
import org.json.JSONArray;
34+
import org.json.JSONException;
3435
import org.json.JSONObject;
3536

3637
import com.hellosign.sdk.HelloSignException;
@@ -229,6 +230,32 @@ public String getExpiresAt() {
229230
return getString(TEMPLATE_EXPIRES_AT);
230231
}
231232

233+
/**
234+
* Helper method to convert a Java Map into the JSON string required
235+
* by the HelloSign API.
236+
* @param mergeFields Map
237+
* @return String
238+
* @throws HelloSignException Thrown if there's a problem parsing JSONObjects
239+
*/
240+
public static String serializeMergeFields(Map<String, FieldType> mergeFields) throws HelloSignException {
241+
if (mergeFields != null) {
242+
JSONArray mergeFieldArray = new JSONArray();
243+
for (String key : mergeFields.keySet()) {
244+
FieldType type = mergeFields.get(key);
245+
JSONObject mergeFieldObj = new JSONObject();
246+
try {
247+
mergeFieldObj.put("name", key);
248+
mergeFieldObj.put("type", type.toString());
249+
} catch (JSONException e) {
250+
throw new HelloSignException(e);
251+
}
252+
mergeFieldArray.put(mergeFieldObj);
253+
}
254+
return mergeFieldArray.toString();
255+
}
256+
return null;
257+
}
258+
232259
/**
233260
* Internal method used to retrieve the necessary POST fields.
234261
*
@@ -251,47 +278,32 @@ public Map<String, Serializable> getPostFields() throws HelloSignException {
251278
List<String> signerRoles = getSignerRoles();
252279
for (int i = 0; i < signerRoles.size(); i++) {
253280
String s = signerRoles.get(i);
254-
255-
// The signers are being ID'd starting at 1, instead of zero.
256-
// This is because the API generates signer IDs for templates
257-
// starting at 1.
258-
// Let's keep this consistent with the API for now.
259-
260-
fields.put("signer_roles[" + (i + 1) + "][name]", s);
261-
281+
fields.put("signer_roles[" + i + "][name]", s);
262282
if (getOrderMatters()) {
263-
fields.put("signer_roles[" + (i + 1) + "][order]", i);
283+
fields.put("signer_roles[" + i + "][order]", i);
264284
}
265285
}
266286

267287
List<String> ccRoles = getCCRoles();
268288
for (int i = 0; i < ccRoles.size(); i++) {
269289
String cc = ccRoles.get(i);
270-
fields.put("cc_roles[" + (i + 1) + "]", cc);
290+
fields.put("cc_roles[" + i + "]", cc);
271291
}
272292

273293
List<Document> docs = getDocuments();
274294
for (int i = 0; i < docs.size(); i++) {
275295
Document d = docs.get(i);
276-
fields.put("file[" + (i + 1) + "]", d.getFile());
296+
fields.put("file[" + i + "]", d.getFile());
277297
}
278298

279299
List<String> fileUrls = getFileUrls();
280300
for (int i = 0; i < fileUrls.size(); i++) {
281301
fields.put("file_url[" + i + "]", fileUrls.get(i));
282302
}
283303

284-
Map<String, FieldType> mergeFields = getMergeFields();
285-
if (mergeFields.size() > 0) {
286-
JSONArray mergeFieldArray = new JSONArray();
287-
for (String key : mergeFields.keySet()) {
288-
FieldType type = mergeFields.get(key);
289-
JSONObject mergeFieldObj = new JSONObject();
290-
mergeFieldObj.put("name", key);
291-
mergeFieldObj.put("type", type.toString());
292-
mergeFieldArray.put(mergeFieldObj);
293-
}
294-
fields.put("merge_fields", mergeFieldArray.toString());
304+
String mergeFieldStr = TemplateDraft.serializeMergeFields(getMergeFields());
305+
if (mergeFieldStr != null) {
306+
fields.put("merge_fields", mergeFieldStr);
295307
}
296308

297309
if (hasUsePreexistingFields()) {

0 commit comments

Comments
 (0)