Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

# [Unreleased]
- Added `templateId` support to `VerificationRequest` for Verify v2 API to allow using custom templates

# [9.7.0] - 2025-12-04
- Added native RCS message types (card, carousel) and suggestions support to eliminate need for custom message type

Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/vonage/client/verify2/VerificationRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Pattern;

/**
Expand All @@ -41,11 +42,13 @@ public class VerificationRequest implements Jsonable {
protected final Integer channelTimeout, codeLength;
protected final Boolean fraudCheck;
protected final String brand, code, clientRef;
protected final UUID templateId;
protected final List<Workflow> workflows;

VerificationRequest(Builder builder) {
locale = builder.locale;
clientRef = builder.clientRef;
templateId = builder.templateId;
fraudCheck = builder.fraudCheck != null && !builder.fraudCheck ? false : null;
if ((brand = builder.brand) == null || brand.trim().isEmpty()) {
throw new IllegalArgumentException("Brand name is required.");
Expand Down Expand Up @@ -179,6 +182,17 @@ public boolean isCodeless() {
return workflows.stream().allMatch(type -> type instanceof SilentAuthWorkflow);
}

/**
* A custom template ID to use for the verification request.
* This allows you to use a pre-configured template instead of the default verification message.
*
* @return The template ID, or {@code null} if not set.
*/
@JsonProperty("template_id")
public UUID getTemplateId() {
return templateId;
}

/**
* Entry point for constructing an instance of this class.
*
Expand All @@ -193,6 +207,7 @@ public static final class Builder {
String brand, code, clientRef;
Integer timeout, codeLength;
Locale locale;
UUID templateId;
final List<Workflow> workflows = new ArrayList<>(1);

private Builder() {}
Expand Down Expand Up @@ -364,6 +379,20 @@ public Builder fraudCheck() {
return fraudCheck(false);
}

/**
* (OPTIONAL)
* A custom template ID to use for the verification request.
* This allows you to use a pre-configured template instead of the default verification message.
*
* @param templateId The UUID of the template to use.
*
* @return This builder.
*/
public Builder templateId(UUID templateId) {
this.templateId = templateId;
return this;
}

/**
* Constructs a VerificationRequest with this builder's properties.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.UUID;

public class VerificationRequestTest {
static final boolean SANDBOX = true;
Expand All @@ -39,6 +40,7 @@ public class VerificationRequestTest {
CONTENT_ID = "1107158078772563946",
ENTITY_ID = "1101407360000017170",
REDIRECT_URL = "https://acme-app.com/sa/redirect";
static final UUID TEMPLATE_ID = UUID.fromString("8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9");

Builder newBuilder() {
return VerificationRequest.builder().brand(BRAND);
Expand Down Expand Up @@ -371,4 +373,41 @@ class SelfRefrencing extends VerificationRequest {
.addWorkflow(new SmsWorkflow(TO_NUMBER)).brand("Test")).toJson()
);
}

@Test
public void testTemplateId() {
Builder builder = getBuilderRequiredParamsSingleWorkflow(Channel.SMS);
VerificationRequest request = builder.build();
assertNull(request.getTemplateId());

builder.templateId(TEMPLATE_ID);
request = builder.build();
assertEquals(TEMPLATE_ID, request.getTemplateId());

String json = request.toJson();
assertTrue(json.contains("\"template_id\":\"" + TEMPLATE_ID + "\""));
}

@Test
public void testTemplateIdInJson() {
for (Channel channel : Channel.values()) {
Builder builder = getBuilderRequiredParamsSingleWorkflow(channel);
builder.templateId(TEMPLATE_ID);
VerificationRequest request = builder.build();
String json = request.toJson();
assertTrue(json.contains("\"template_id\":\"" + TEMPLATE_ID + "\""),
"template_id should be included in JSON for " + channel);
}
}

@Test
public void testTemplateIdNotIncludedWhenNull() {
for (Channel channel : Channel.values()) {
Builder builder = getBuilderRequiredParamsSingleWorkflow(channel);
VerificationRequest request = builder.build();
String json = request.toJson();
assertFalse(json.contains("\"template_id\""),
"template_id should not be included in JSON when null for " + channel);
}
}
}