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}