001/*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package dev.enola.audio.voice.twilio.relay;
019
020import com.fasterxml.jackson.annotation.JsonSubTypes;
021import com.fasterxml.jackson.annotation.JsonTypeInfo;
022
023import dev.enola.audio.voice.twilio.relay.ConversationRelayRequest.DTMF;
024import dev.enola.audio.voice.twilio.relay.ConversationRelayRequest.Error;
025import dev.enola.audio.voice.twilio.relay.ConversationRelayRequest.Interrupt;
026import dev.enola.audio.voice.twilio.relay.ConversationRelayRequest.Prompt;
027import dev.enola.audio.voice.twilio.relay.ConversationRelayRequest.Setup;
028
029import java.util.Locale;
030import java.util.Map;
031
032/**
033 * Twilio's <a
034 * href="https://www.twilio.com/docs/voice/conversationrelay/websocket-messages">ConversationRelay
035 * request messages</a> JSON format.
036 */
037@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
038@JsonSubTypes({
039    @JsonSubTypes.Type(value = Setup.class, name = "setup"),
040    @JsonSubTypes.Type(value = Prompt.class, name = "prompt"),
041    @JsonSubTypes.Type(value = DTMF.class, name = "dtmf"),
042    @JsonSubTypes.Type(value = Interrupt.class, name = "interrupt"),
043    @JsonSubTypes.Type(value = Error.class, name = "error")
044})
045public sealed interface ConversationRelayRequest {
046
047    record Setup(
048            String sessionId,
049            String callSid,
050            String parentCallSid,
051            String from,
052            String to,
053            String forwardedFrom,
054            String callerName,
055            // TODO Use direction enum { PSTN, ... ? }; escalate to Twilio for missing documentation
056            // String direction,
057            // TODO Use callType enum; escalate to Twilio for missing documentation
058            // String callType,
059            // TODO Use UPPER https://www.twilio.com/docs/voice/api/call-resource#call-status-values
060            // String callStatus,
061            String accountSid,
062            Map<String, Object> customParameters)
063            implements ConversationRelayRequest {}
064
065    record Prompt(String voicePrompt, Locale lang, boolean last)
066            implements ConversationRelayRequest {}
067
068    record DTMF(String digit) implements ConversationRelayRequest {}
069
070    record Interrupt(String utteranceUntilInterrupt, int durationUntilInterruptMs)
071            implements ConversationRelayRequest {}
072
073    record Error(String description) implements ConversationRelayRequest {}
074}