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.*; 019import com.vonage.client.JsonableBaseObject; 020import com.vonage.client.users.User; 021import java.time.Instant; 022import java.util.Objects; 023 024/** 025 * Events are actions that occur within a conversation. 026 */ 027@JsonTypeInfo( 028 use = JsonTypeInfo.Id.NAME, 029 include = JsonTypeInfo.As.EXISTING_PROPERTY, 030 property = "type", 031 visible = true, 032 defaultImpl = GenericEvent.class 033) 034@JsonSubTypes({ 035 @JsonSubTypes.Type(value = EventDeleteEvent.class, name = "event:delete"), 036 @JsonSubTypes.Type(value = ConversationUpdatedEvent.class, name = "conversation:updated"), 037 @JsonSubTypes.Type(value = MessageSeenEvent.class, name = "message:seen"), 038 @JsonSubTypes.Type(value = MessageSubmittedEvent.class, name = "message:submitted"), 039 @JsonSubTypes.Type(value = MessageDeliveredEvent.class, name = "message:delivered"), 040 @JsonSubTypes.Type(value = MessageUndeliverableEvent.class, name = "message:undeliverable"), 041 @JsonSubTypes.Type(value = MessageRejectedEvent.class, name = "message:rejected"), 042 @JsonSubTypes.Type(value = AudioPlayEvent.class, name = "audio:play"), 043 @JsonSubTypes.Type(value = AudioPlayStopEvent.class, name = "audio:play:stop"), 044 @JsonSubTypes.Type(value = AudioPlayDoneEvent.class, name = "audio:play:done"), 045 @JsonSubTypes.Type(value = AudioSayEvent.class, name = "audio:say"), 046 @JsonSubTypes.Type(value = AudioSayStopEvent.class, name = "audio:say:stop"), 047 @JsonSubTypes.Type(value = AudioSayDoneEvent.class, name = "audio:say:done"), 048 @JsonSubTypes.Type(value = AudioRecordEvent.class, name = "audio:record"), 049 @JsonSubTypes.Type(value = AudioRecordStopEvent.class, name = "audio:record:stop"), 050 @JsonSubTypes.Type(value = AudioMuteOnEvent.class, name = "audio:mute:on"), 051 @JsonSubTypes.Type(value = AudioMuteOffEvent.class, name = "audio:mute:off"), 052 @JsonSubTypes.Type(value = AudioEarmuffOnEvent.class, name = "audio:earmuff:on"), 053 @JsonSubTypes.Type(value = AudioEarmuffOffEvent.class, name = "audio:earmuff:off"), 054 @JsonSubTypes.Type(value = EphemeralEvent.class, name = "ephemeral"), 055 @JsonSubTypes.Type(value = CustomEvent.class, name = "custom") 056}) 057public abstract class Event extends JsonableBaseObject { 058 @JsonIgnore String conversationId; 059 @JsonProperty("type") EventType type; 060 @JsonProperty("id") Integer id; 061 @JsonProperty("from") String from; 062 @JsonProperty("timestamp") Instant timestamp; 063 @JsonProperty("_embedded") Embedded _embedded; 064 065 private static class Embedded extends JsonableBaseObject { 066 @JsonProperty("from_user") User fromUser; 067 @JsonProperty("from_member") BaseMember fromMember; 068 } 069 070 protected Event() { 071 } 072 073 Event(Builder<?, ?> builder) { 074 type = Objects.requireNonNull(builder.type, "Event type is required."); 075 from = ConversationsClient.validateMemberId(builder.from); 076 } 077 078 /** 079 * Event id. This is a progressive integer. 080 * 081 * @return The event ID as an integer, or {@code null} if unknown. 082 */ 083 public Integer getId() { 084 return id; 085 } 086 087 /** 088 * Type of event. 089 * 090 * @return The event type as an enum. 091 */ 092 public EventType getType() { 093 return type; 094 } 095 096 /** 097 * Member ID this event was sent from. 098 * 099 * @return The member ID, or {@code null} if unspecified. 100 */ 101 public String getFrom() { 102 return from; 103 } 104 105 /** 106 * Time of creation. 107 * 108 * @return The event timestamp, or {@code null} if unknown. 109 */ 110 public Instant getTimestamp() { 111 return timestamp; 112 } 113 114 /** 115 * Details about the user that initiated the event. 116 * 117 * @return The embedded {@code from_user} object, or {@code null} if absent. 118 */ 119 @JsonIgnore 120 public User getFromUser() { 121 return _embedded != null ? _embedded.fromUser : null; 122 } 123 124 /** 125 * Member that initiated the event. Only the {@code id} field will be present. 126 * 127 * @return The embedded {@code from_member} object, or {@code null} if absent. 128 */ 129 @JsonIgnore 130 public BaseMember getFromMember() { 131 return _embedded != null ? _embedded.fromMember : null; 132 } 133 134 /** 135 * Builder for constructing an event request's parameters. 136 * 137 * @param <E> The event type. 138 * @param <B> The builder type. 139 */ 140 @SuppressWarnings("unchecked") 141 public abstract static class Builder<E extends Event, B extends Builder<? extends E, ? extends B>> { 142 private final EventType type; 143 private String from; 144 145 /** 146 * Construct a new builder for a given event type. 147 * 148 * @param type The event type as an enum. 149 */ 150 protected Builder(EventType type) { 151 this.type = type; 152 } 153 154 /** 155 * Member ID this event was sent from. 156 * 157 * @param from The member ID, or {@code null} if unspecified. 158 * 159 * @return This builder. 160 */ 161 public B from(String from) { 162 this.from = from; 163 return (B) this; 164 } 165 166 /** 167 * Builds the {@linkplain EventWithBody}. 168 * 169 * @return An instance of Event, populated with all fields from this builder. 170 */ 171 public abstract E build(); 172 } 173}