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}