From c3d415878d1fdd9c784b814d078b959bfe434032 Mon Sep 17 00:00:00 2001 From: onedge Date: Fri, 5 Dec 2025 08:18:48 +0900 Subject: [PATCH] feat: Add template_id support to VerificationRequest - Add templateId field to VerificationRequest class - Add templateId(UUID) builder method - Add getTemplateId() getter with @JsonProperty annotation - Add comprehensive unit tests - Update CHANGELOG.md This change adds support for using custom templates in verification requests, allowing users to specify a template_id when creating verification requests via the Verify v2 API. --- CHANGELOG.md | 3 ++ .../client/verify2/VerificationRequest.java | 29 ++++++++++++++ .../verify2/VerificationRequestTest.java | 39 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12ec65060..03caf2f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/main/java/com/vonage/client/verify2/VerificationRequest.java b/src/main/java/com/vonage/client/verify2/VerificationRequest.java index 9a2ebea66..c4a2093e2 100644 --- a/src/main/java/com/vonage/client/verify2/VerificationRequest.java +++ b/src/main/java/com/vonage/client/verify2/VerificationRequest.java @@ -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; /** @@ -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 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."); @@ -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. * @@ -193,6 +207,7 @@ public static final class Builder { String brand, code, clientRef; Integer timeout, codeLength; Locale locale; + UUID templateId; final List workflows = new ArrayList<>(1); private Builder() {} @@ -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. * diff --git a/src/test/java/com/vonage/client/verify2/VerificationRequestTest.java b/src/test/java/com/vonage/client/verify2/VerificationRequestTest.java index 8187ff69a..7859e1d0e 100644 --- a/src/test/java/com/vonage/client/verify2/VerificationRequestTest.java +++ b/src/test/java/com/vonage/client/verify2/VerificationRequestTest.java @@ -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; @@ -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); @@ -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); + } + } }