Skip to content

Commit fabd16a

Browse files
committed
feat: Add Verify custom templates
1 parent eefe856 commit fabd16a

File tree

5 files changed

+515
-7
lines changed

5 files changed

+515
-7
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>com.vonage</groupId>
77
<artifactId>server-sdk-kotlin</artifactId>
8-
<version>1.0.0</version>
8+
<version>1.1.0</version>
99

1010
<name>Vonage Kotlin Server SDK</name>
1111
<description>Kotlin client for Vonage APIs</description>
@@ -55,7 +55,7 @@
5555
<dependency>
5656
<groupId>com.vonage</groupId>
5757
<artifactId>server-sdk</artifactId>
58-
<version>8.12.0</version>
58+
<version>8.13.0</version>
5959
</dependency>
6060
<dependency>
6161
<groupId>org.jetbrains.kotlin</groupId>

src/main/kotlin/com/vonage/client/kt/Verify.kt

Lines changed: 244 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ class Verify(private val client: Verify2Client) {
4848
properties: VerificationRequest.Builder.() -> Unit): VerificationResponse =
4949
client.sendVerification(VerificationRequest.builder().brand(brand).apply(properties).build())
5050

51-
5251
/**
5352
* Call this method to work with an existing verification request.
5453
*
@@ -67,7 +66,7 @@ class Verify(private val client: Verify2Client) {
6766
fun request(requestId: String): ExistingRequest = request(UUID.fromString(requestId))
6867

6968
/**
70-
* Call this method to work with an existing verification request.
69+
* Class for working with an existing verification request.
7170
*
7271
* @param uuid UUID of the verification request to work with, as obtained from [VerificationResponse.getRequestId].
7372
*/
@@ -106,12 +105,14 @@ class Verify(private val client: Verify2Client) {
106105
*
107106
* @return A [VerifyCodeResponse] object containing the verification status.
108107
*
109-
* @throws [VerifyResponseException] If the code could not be checked. This could be for the following reasons:
108+
* @throws [VerifyResponseException] If the check fails. This could be for the following reasons:
110109
* - **400**: Invalid code.
111110
* - **401**: Invalid credentials.
111+
* - **402**: Account balance too low.
112112
* - **404**: Request was not found, or it has been verified already.
113113
* - **409**: The current workflow does not support a code.
114114
* - **410**: An incorrect code has been provided too many times. Workflow terminated.
115+
* - **429**: Rate limit exceeded.
115116
* - **500**: Internal server error.
116117
*
117118
* @see isValidVerificationCode For a Boolean-returning version of this method.
@@ -126,6 +127,15 @@ class Verify(private val client: Verify2Client) {
126127
* @param code The verification code to check, as entered by the user.
127128
*
128129
* @return `true` if the code is valid, `false` if it is not.
130+
*
131+
* @throws [VerifyResponseException] If the code could not be checked. This could be for the following reasons:
132+
* - **401**: Invalid credentials.
133+
* - **402**: Account balance too low.
134+
* - **404**: Request was not found, or it has been verified already.
135+
* - **409**: The current workflow does not support a code.
136+
* - **429**: Rate limit exceeded.
137+
* - **500**: Internal server error.
138+
*
129139
* @see checkVerificationCode For the original implementation which this method delegates to.
130140
*/
131141
fun isValidVerificationCode(code: String): Boolean {
@@ -141,6 +151,237 @@ class Verify(private val client: Verify2Client) {
141151
}
142152
}
143153
}
154+
155+
/**
156+
* Create a new custom template.
157+
*
158+
* @param name Reference name for the template. Must not contain spaces or special characters than `_` and `-`.
159+
*
160+
* @return Details of the created template.
161+
*
162+
* @throws [VerifyResponseException] If the template could not be created. This could be for the following reasons:
163+
* - **401**: Invalid credentials.
164+
* - **402**: Account balance too low.
165+
* - **403**: Template management is not enabled for your account.
166+
* - **409**: Template with the same name already exists, or you have 10 templates already.
167+
* - **429**: Rate limit exceeded.
168+
* - **500**: Internal server error.
169+
*
170+
* @since 1.1.0
171+
*/
172+
fun createTemplate(name: String): Template = client.createTemplate(name)
173+
174+
/**
175+
* List all custom templates for your application.
176+
*
177+
* @return A list of all custom templates.
178+
*
179+
* @throws [VerifyResponseException] If the templates could not be listed. This could be for the following reasons:
180+
* - **401**: Invalid credentials.
181+
* - **402**: Account balance too low.
182+
* - **429**: Rate limit exceeded.
183+
* - **500**: Internal server error.
184+
*
185+
* @since 1.1.0
186+
*/
187+
fun listTemplates(): List<Template> = client.listTemplates()
188+
189+
/**
190+
* Call this method to work with an existing custom template.
191+
*
192+
* @param templateId ID of the template to work with as a string.
193+
*
194+
* @return An [ExistingTemplate] object with methods to interact with the template.
195+
*
196+
* @since 1.1.0
197+
*/
198+
fun template(templateId: String): ExistingTemplate = ExistingTemplate(templateId)
199+
200+
/**
201+
* Class for working with an existing custom template.
202+
*
203+
* @param templateId UUID of the template to work with, as obtained from [Template.getId].
204+
*
205+
* @since 1.1.0
206+
*/
207+
inner class ExistingTemplate internal constructor(id: String): ExistingResource(id) {
208+
private val templateId = UUID.fromString(id)
209+
210+
/**
211+
* Get the custom template.
212+
*
213+
* @return Details of the custom template.
214+
*
215+
* @throws [VerifyResponseException] If the template could not be retrieved. This could be for the following reasons:
216+
* - **401**: Invalid credentials.
217+
* - **402**: Account balance too low.
218+
* - **404**: Template not found.
219+
* - **429**: Rate limit exceeded.
220+
* - **500**: Internal server error.
221+
*
222+
* @since 1.1.0
223+
*/
224+
fun get(): Template = client.getTemplate(templateId)
225+
226+
/**
227+
* Update the custom template. Note that you must specify at least one parameter to change.
228+
*
229+
* @param name (OPTIONAL) New reference name for the template.
230+
* Must not contain spaces or special characters besides `_` and `-`.
231+
*
232+
* @param isDefault (OPTIONAL) Whether to set this template as the default.
233+
*
234+
* @return Details of the updated template.
235+
*
236+
* @throws [VerifyResponseException] If the template could not be updated. This could be for the following reasons:
237+
* - **401**: Invalid credentials.
238+
* - **402**: Account balance too low.
239+
* - **403**: Template management is not enabled for your account.
240+
* - **404**: Template not found.
241+
* - **409**: Template with this name already exists.
242+
* - **429**: Rate limit exceeded.
243+
* - **500**: Internal server error.
244+
*
245+
* @since 1.1.0
246+
*/
247+
fun update(name: String? = null, isDefault: Boolean? = null): Template =
248+
client.updateTemplate(templateId, name, isDefault)
249+
250+
/**
251+
* Delete the custom template.
252+
*
253+
* @throws [VerifyResponseException] If the template could not be deleted. This could be for the following reasons:
254+
* - **401**: Invalid credentials.
255+
* - **402**: Account balance too low.
256+
* - **403**: Template management is not enabled for your account.
257+
* - **404**: Template not found.
258+
* - **409**: Template is the default or contains undeleted fragments.
259+
* - **429**: Rate limit exceeded.
260+
* - **500**: Internal server error.
261+
*
262+
* @since 1.1.0
263+
*/
264+
fun delete(): Unit = client.deleteTemplate(templateId)
265+
266+
/**
267+
* Create a new template fragment.
268+
*
269+
* @param text Text content of the template. There are 4 reserved variables available to use:
270+
* `${code}`, `${brand}`, `${time-limit}` and `${time-limit-unit}`. You must always use `${code}`.
271+
* @param locale BCP-47 locale of the fragment.
272+
* @param channel The channel for the fragment.
273+
*
274+
* @return Details of the created fragment.
275+
*
276+
* @throws [VerifyResponseException] If the fragment could not be created.
277+
* This could be for the following reasons:
278+
*
279+
* - **401**: Invalid credentials.
280+
* - **402**: Account balance too low.
281+
* - **403**: Template management is not enabled for your account.
282+
* - **404**: Template not found.
283+
* - **409**: Fragment with the same locale and channel already exists.
284+
* - **429**: Rate limit exceeded.
285+
* - **500**: Internal server error.
286+
*
287+
* @since 1.1.0
288+
*/
289+
fun createFragment(text: String, locale: String, channel: FragmentChannel): TemplateFragment =
290+
client.createTemplateFragment(templateId, TemplateFragment(channel, locale, text))
291+
292+
/**
293+
* List all template fragments for the template.
294+
*
295+
* @return A list of all template fragments.
296+
*
297+
* @throws [VerifyResponseException] If the fragments could not be listed.
298+
* This could be for the following reasons:
299+
* - **401**: Invalid credentials.
300+
* - **402**: Account balance too low.
301+
* - **404**: Template not found.
302+
* - **429**: Rate limit exceeded.
303+
* - **500**: Internal server error.
304+
*
305+
* @since 1.1.0
306+
*/
307+
fun listFragments(): List<TemplateFragment> = client.listTemplateFragments(templateId)
308+
309+
/**
310+
* Call this method to work with an existing template fragment.
311+
*
312+
* @param fragmentId ID of the fragment to work with as a string.
313+
*
314+
* @return An [ExistingTemplateFragment] object with methods to interact with the fragment.
315+
*
316+
* @since 1.1.0
317+
*/
318+
fun fragment(fragmentId: String): ExistingTemplateFragment = ExistingTemplateFragment(fragmentId)
319+
320+
/**
321+
* Class for working with an existing template fragment.
322+
*
323+
* @param fragmentId UUID of the fragment to work with, as obtained from [TemplateFragment.getId].
324+
*
325+
* @since 1.1.0
326+
*/
327+
inner class ExistingTemplateFragment internal constructor(id: String): ExistingResource(id) {
328+
private val fragmentId = UUID.fromString(id)
329+
330+
/**
331+
* Get the template fragment.
332+
*
333+
* @return Details of the template fragment.
334+
*
335+
* @throws [VerifyResponseException] If the fragment could not be retrieved.
336+
* This could be for the following reasons:
337+
* - **401**: Invalid credentials.
338+
* - **402**: Account balance too low.
339+
* - **404**: Fragment not found.
340+
* - **429**: Rate limit exceeded.
341+
* - **500**: Internal server error.
342+
*
343+
* @since 1.1.0
344+
*/
345+
fun get(): TemplateFragment = client.getTemplateFragment(templateId, fragmentId)
346+
347+
/**
348+
* Update the template fragment.
349+
*
350+
* @param text New text for the fragment. There are 4 reserved variables available to use:
351+
*`${code}`, `${brand}`, `${time-limit}` and `${time-limit-unit}`. You must always use `${code}`.
352+
*
353+
* @return Details of the updated fragment.
354+
*
355+
* @throws [VerifyResponseException] If the fragment could not be updated.
356+
* This could be for the following reasons:
357+
* - **401**: Invalid credentials.
358+
* - **402**: Account balance too low.
359+
* - **403**: Template management is not enabled for your account.
360+
* - **404**: Fragment not found.
361+
* - **429**: Rate limit exceeded.
362+
* - **500**: Internal server error.
363+
*
364+
* @since 1.1.0
365+
*/
366+
fun update(text: String): TemplateFragment = client.updateTemplateFragment(templateId, fragmentId, text)
367+
368+
/**
369+
* Delete the template fragment.
370+
*
371+
* @throws [VerifyResponseException] If the fragment could not be deleted.
372+
* This could be for the following reasons:
373+
* - **401**: Invalid credentials.
374+
* - **402**: Account balance too low.
375+
* - **403**: Template management is not enabled for your account.
376+
* - **404**: Fragment not found.
377+
* - **429**: Rate limit exceeded.
378+
* - **500**: Internal server error.
379+
*
380+
* @since 1.1.0
381+
*/
382+
fun delete(): Unit = client.deleteTemplateFragment(templateId, fragmentId)
383+
}
384+
}
144385
}
145386

146387
/**

src/main/kotlin/com/vonage/client/kt/Vonage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.vonage.client.kt
1818
import com.vonage.client.HttpConfig
1919
import com.vonage.client.VonageClient
2020

21-
const val VONAGE_KOTLIN_SDK_VERSION = "1.0.0"
21+
const val VONAGE_KOTLIN_SDK_VERSION = "1.1.0"
2222
private const val SDK_USER_AGENT = "vonage-kotlin-sdk/$VONAGE_KOTLIN_SDK_VERSION"
2323

2424
/**

src/test/kotlin/com/vonage/client/kt/AbstractTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ abstract class AbstractTest {
5656
private val basicSecretEncodedHeader = "Basic $apiKeySecretEncoded"
5757
private val jwtBearerPattern = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9(\\..+){2}"
5858
private val accessTokenBearer = "Bearer $accessToken"
59+
protected val apiBaseUrl = "https://api.nexmo.com"
5960
protected val testUuidStr = "aaaaaaaa-bbbb-4ccc-8ddd-0123456789ab"
6061
protected val testUuid: UUID = UUID.fromString(testUuidStr)
6162
protected val randomUuid: UUID = UUID.randomUUID()

0 commit comments

Comments
 (0)