001/* 002 * Copyright 2024 Vonage 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.vonage.client.conversations; 017 018import com.fasterxml.jackson.annotation.JsonProperty; 019import com.vonage.client.users.channels.Channel; 020import com.vonage.client.users.channels.Pstn; 021import java.net.URI; 022import java.util.ArrayList; 023import java.util.Arrays; 024import java.util.Collection; 025 026/** 027 * Represents a Conversation (request and response). 028 */ 029public class Conversation extends BaseConversation { 030 private ConversationStatus state; 031 private Integer sequenceNumber; 032 private ConversationProperties properties; 033 private Collection<? extends Channel> numbers; 034 private Callback callback; 035 036 protected Conversation() { 037 } 038 039 Conversation(Builder builder) { 040 if ((name = builder.name) != null && (name.length() > 100 || name.trim().isEmpty())) { 041 throw new IllegalArgumentException("Name must be between 1 and 100 characters."); 042 } 043 if ((displayName = builder.displayName) != null && (displayName.length() > 50 || displayName.trim().isEmpty())) { 044 throw new IllegalArgumentException("Display name must be between 1 and 50 characters."); 045 } 046 imageUrl = builder.imageUrl; 047 properties = builder.properties; 048 callback = builder.callback; 049 if ((numbers = builder.numbers) != null) { 050 numbers.forEach(Channel::setTypeField); 051 } 052 } 053 054 /** 055 * The state the conversation is in. 056 * 057 * @return The conversation state as an enum, or {@code null} if unknown. 058 */ 059 @JsonProperty("state") 060 public ConversationStatus getState() { 061 return state; 062 } 063 064 /** 065 * The last Event ID in this conversation. This ID can be used to retrieve a specific event. 066 * 067 * @return The last event ID as an integer, or {@code null} if unknown. 068 */ 069 @JsonProperty("sequence_number") 070 public Integer getSequenceNumber() { 071 return sequenceNumber; 072 } 073 074 /** 075 * Properties for this conversation. 076 * 077 * @return The conversation properties object, or {@code null} if not applicable. 078 */ 079 @JsonProperty("properties") 080 public ConversationProperties getProperties() { 081 return properties; 082 } 083 084 /** 085 * Channels containing the contact numbers for this conversation. 086 * Currently, only {@link Pstn} (Phone) type is supported. 087 * 088 * @return The channels associated with this conversation, or {@code null} if unspecified. 089 */ 090 @JsonProperty("numbers") 091 public Collection<? extends Channel> getNumbers() { 092 return numbers; 093 } 094 095 /** 096 * Specifies callback parameters for webhooks. 097 * 098 * @return The callback properties, or {@code null} if unspecified. 099 */ 100 @JsonProperty("callback") 101 public Callback getCallback() { 102 return callback; 103 } 104 105 /** 106 * Entry point for constructing an instance of this class. 107 * 108 * @return A new Builder. 109 */ 110 public static Builder builder() { 111 return new Builder(); 112 } 113 114 /** 115 * Builder for creating or updating a Conversation. All fields are optional. 116 */ 117 public static class Builder { 118 private String name, displayName; 119 private URI imageUrl; 120 private ConversationProperties properties; 121 private Collection<? extends Channel> numbers; 122 private Callback callback; 123 124 Builder() {} 125 126 /** 127 * Internal conversation name. Must be unique. 128 * 129 * @param name The conversation name. 130 * 131 * @return This builder. 132 */ 133 public Builder name(String name) { 134 this.name = name; 135 return this; 136 } 137 138 /** 139 * The public facing name of the conversation. 140 * 141 * @param displayName The display name. 142 * 143 * @return This builder. 144 */ 145 public Builder displayName(String displayName) { 146 this.displayName = displayName; 147 return this; 148 } 149 150 /** 151 * An image URL that you associate with the conversation. 152 * 153 * @param imageUrl The image URL as a string. 154 * 155 * @return This builder. 156 */ 157 public Builder imageUrl(String imageUrl) { 158 this.imageUrl = URI.create(imageUrl); 159 return this; 160 } 161 162 /** 163 * Properties for this conversation. 164 * 165 * @param properties The conversation properties object. 166 * 167 * @return This builder. 168 */ 169 public Builder properties(ConversationProperties properties) { 170 this.properties = properties; 171 return this; 172 } 173 174 /** 175 * Sets the PSTN numbers for this conversation. 176 * 177 * @param phoneNumber The telephone or mobile number(s) for this conversation in E.164 format. 178 * 179 * @return This builder. 180 */ 181 public Builder phone(String... phoneNumber) { 182 return numbers(Arrays.stream(phoneNumber).map(Pstn::new).toArray(Channel[]::new)); 183 } 184 185 /** 186 * Channels containing the contact numbers for this conversation. 187 * 188 * @param numbers The channels associated with this conversation. 189 * 190 * @return This builder. 191 */ 192 Builder numbers(Channel... numbers) { 193 return numbers(Arrays.asList(numbers)); 194 } 195 196 /** 197 * Channels containing the contact numbers for this conversation. 198 * 199 * @param numbers The channels associated with this conversation. 200 * 201 * @return This builder. 202 */ 203 Builder numbers(Collection<? extends Channel> numbers) { 204 this.numbers = new ArrayList<>(numbers); 205 return this; 206 } 207 208 /** 209 * Specifies callback parameters for webhooks. 210 * 211 * @param callback The callback properties, or {@code null} if unspecified. 212 * 213 * @return This builder. 214 */ 215 public Builder callback(Callback callback) { 216 this.callback = callback; 217 return this; 218 } 219 220 /** 221 * Builds the {@linkplain Conversation}. 222 * 223 * @return An instance of Conversation, populated with all fields from this builder. 224 */ 225 public Conversation build() { 226 return new Conversation(this); 227 } 228 } 229}