diff --git a/types/jambonz__node-client/.npmignore b/types/jambonz__node-client/.npmignore new file mode 100644 index 00000000000000..93e307400a5456 --- /dev/null +++ b/types/jambonz__node-client/.npmignore @@ -0,0 +1,5 @@ +* +!**/*.d.ts +!**/*.d.cts +!**/*.d.mts +!**/*.d.*.ts diff --git a/types/jambonz__node-client/index.d.ts b/types/jambonz__node-client/index.d.ts new file mode 100644 index 00000000000000..437b74dc1dbce1 --- /dev/null +++ b/types/jambonz__node-client/index.d.ts @@ -0,0 +1,1470 @@ +// ============================================ +// Verb Payload Types (from specs.json) +// ============================================ + +interface ActionHookDelayAction { + enabled?: boolean; + noResponseTimeout?: number; + noResponseGiveUpTimeout?: number; + retries?: number; + actions?: unknown[]; + giveUpActions?: unknown[]; +} + +interface Amd { + actionHook: Record | string; + thresholdWordCount?: number; + digitCount?: number; + timers?: AmdTimers; + recognizer?: Recognizer; +} + +interface AmdTimers { + noSpeechTimeoutMs?: number; + decisionTimeoutMs?: number; + toneTimeoutMs?: number; + greetingCompletionTimeoutMs?: number; +} + +interface AssemblyAiOptions { + apiKey?: string; + serviceVersion?: "v2" | "v3"; + formatTurns?: boolean; + endOfTurnConfidenceThreshold?: number; + minEndOfTurnSilenceWhenConfident?: number; + maxTurnSilence?: number; +} + +interface Auth { + username: string; + password: string; +} + +interface AwsOptions { + accessKey?: string; + secretKey?: string; + securityToken?: string; + region?: string; + vocabularyName?: string; + vocabularyFilterName?: string; + vocabularyFilterMethod?: "remove" | "mask" | "tag"; + languageModelName?: string; + piiEntityTypes?: unknown[]; + piiIdentifyEntities?: boolean; +} + +interface AzureOptions { + speechSegmentationSilenceTimeoutMs?: number; + postProcessing?: string; + audioLogging?: boolean; + languageIdMode?: "AtStart" | "Continuous"; + speechRecognitionMode?: "CONVERSATION" | "DICTATION" | "INTERACTIVE"; +} + +interface BargeIn { + enable: boolean; + sticky?: boolean; + actionHook?: Record | string; + partialResultHook?: Record | string; + input?: unknown[]; + finishOnKey?: string; + numDigits?: number; + minDigits?: number; + maxDigits?: number; + interDigitTimeout?: number; + dtmfBargein?: boolean; + minBargeinWordCount?: number; +} + +interface BidirectionalAudio { + enabled?: boolean; + streaming?: boolean; + sampleRate?: number; +} + +interface CobaltOptions { + serverUri?: string; + enableConfusionNetwork?: boolean; + metadata?: string; + compiledContextData?: string; + wordTimeOffsets?: boolean; + contextToken?: string; +} + +interface CustomOptions { + authToken?: string; + uri?: string; + sampleRate?: number; + options?: Record; +} + +interface DeepgramOptions { + deepgramSttUri?: string; + deepgramSttUseTls?: boolean; + apiKey?: string; + tier?: string; + model?: string; + customModel?: string; + version?: string; + punctuate?: boolean; + smartFormatting?: boolean; + noDelay?: boolean; + profanityFilter?: boolean; + redact?: "pci" | "numbers" | "true" | "ssn"; + diarize?: boolean; + diarizeVersion?: string; + ner?: boolean; + multichannel?: boolean; + alternatives?: number; + numerals?: boolean; + search?: unknown[]; + replace?: unknown[]; + keywords?: unknown[]; + keyterms?: unknown[]; + endpointing?: boolean | number; + utteranceEndMs?: number; + shortUtterance?: boolean; + vadTurnoff?: number; + tag?: string; + fillerWords?: boolean; + eotThreshold?: number; + eotTimeoutMs?: number; + mipOptOut?: boolean; + entityPrompt?: string; + eagerEotThreshold?: number; +} + +interface DialFrom { + user?: string; + host?: string; +} + +interface ElevenlabsOptions { + includeTimestamps?: boolean; + commitStrategy?: "manual" | "vad"; + vadSilenceThresholdSecs?: number; + vadThreshold?: number; + minSpeechDurationMs?: number; + minSilenceDurationMs?: number; + enableLogging?: boolean; +} + +interface FillerNoise { + enable: boolean; + url?: string; + startDelaySecs?: number; +} + +interface Formatting { + scheme: string; + options: Record; +} + +interface GoogleOptions { + serviceVersion?: "v1" | "v2"; + recognizerId?: string; + speechStartTimeoutMs?: number; + speechEndTimeoutMs?: number; + enableVoiceActivityEvents?: boolean; + transcriptNormalization?: unknown[]; +} + +interface HoundifyOptions { + requestInfo?: Record; + sampleRate?: number; + latitude?: number; + longitude?: number; + city?: string; + state?: string; + country?: string; + timeZone?: string; + domain?: string; + audioEndpoint?: string; + maxSilenceSeconds?: number; + maxSilenceAfterFullQuerySeconds?: number; + maxSilenceAfterPartialQuerySeconds?: number; + vadSensitivity?: number; + vadTimeout?: number; + vadMode?: string; + vadVoiceMs?: number; + vadSilenceMs?: number; + vadDebug?: boolean; + audioFormat?: string; + enableNoiseReduction?: boolean; + enableProfanityFilter?: boolean; + enablePunctuation?: boolean; + enableCapitalization?: boolean; + confidenceThreshold?: number; + enableDisfluencyFilter?: boolean; + maxResults?: number; + enableWordTimestamps?: boolean; + maxAlternatives?: number; + partialTranscriptInterval?: number; + sessionTimeout?: number; + connectionTimeout?: number; + customVocabulary?: unknown[]; + languageModel?: string; +} + +interface IbmOptions { + sttApiKey?: string; + sttRegion?: string; + ttsApiKey?: string; + ttsRegion?: string; + instanceId?: string; + model?: string; + languageCustomizationId?: string; + acousticCustomizationId?: string; + baseModelVersion?: string; + watsonMetadata?: string; + watsonLearningOptOut?: boolean; +} + +interface LexIntent { + name: string; + slots?: Record; +} + +interface ListenOptions { + enable: boolean; + url?: string; + sampleRate?: number; + wsAuth?: Auth; + mixType?: "mono" | "stereo" | "mixed"; + metadata?: Record; + maxLength?: number; + passDtmf?: boolean; + playBeep?: boolean; + disableBidirectionalAudio?: boolean; + bidirectionalAudio?: BidirectionalAudio; + timeout?: number; +} + +interface McpServer { + url: string; + auth?: Record; + roots?: unknown[]; +} + +interface NuanceOptions { + clientId?: string; + secret?: string; + kryptonEndpoint?: string; + topic?: string; + utteranceDetectionMode?: "single" | "multiple" | "disabled"; + punctuation?: boolean; + profanityFilter?: boolean; + includeTokenization?: boolean; + discardSpeakerAdaptation?: boolean; + suppressCallRecording?: boolean; + maskLoadFailures?: boolean; + suppressInitialCapitalization?: boolean; + allowZeroBaseLmWeight?: boolean; + filterWakeupWord?: boolean; + resultType?: "final" | "partial" | "immutable_partial"; + noInputTimeoutMs?: number; + recognitionTimeoutMs?: number; + utteranceEndSilenceMs?: number; + maxHypotheses?: number; + speechDomain?: string; + formatting?: Formatting; + clientData?: Record; + userId?: string; + speechDetectionSensitivity?: number; + resources?: Resource[]; +} + +interface NvidiaOptions { + rivaUri?: string; + maxAlternatives?: number; + profanityFilter?: boolean; + punctuation?: boolean; + wordTimeOffsets?: boolean; + verbatimTranscripts?: boolean; + customConfiguration?: Record; +} + +interface OpenaiOptions { + apiKey?: string; + model?: string; + prompt?: string; + promptTemplates?: PromptTemplates; + language?: string; + input_audio_noise_reduction?: "near_field" | "far_field"; + turn_detection?: TurnDetection; +} + +interface PromptTemplates { + hintsTemplate?: string; + conversationHistoryTemplate?: string; +} + +interface QueryInput { + text?: string; + intent?: string; + event?: string; + dtmf?: string; +} + +interface Recognizer { + vendor: string; + label?: string; + language?: string; + fallbackVendor?: string; + fallbackLabel?: string; + fallbackLanguage?: string; + vad?: Vad; + hints?: unknown[]; + hintsBoost?: number; + altLanguages?: unknown[]; + profanityFilter?: boolean; + interim?: boolean; + singleUtterance?: boolean; + dualChannel?: boolean; + separateRecognitionPerChannel?: boolean; + punctuation?: boolean; + enhancedModel?: boolean; + words?: boolean; + diarization?: boolean; + diarizationMinSpeakers?: number; + diarizationMaxSpeakers?: number; + interactionType?: + | "unspecified" + | "discussion" + | "presentation" + | "phone_call" + | "voicemail" + | "voice_search" + | "voice_command" + | "dictation"; + naicsCode?: number; + identifyChannels?: boolean; + vocabularyName?: string; + vocabularyFilterName?: string; + filterMethod?: "remove" | "mask" | "tag"; + model?: string; + outputFormat?: "simple" | "detailed"; + profanityOption?: "masked" | "removed" | "raw"; + requestSnr?: boolean; + initialSpeechTimeoutMs?: number; + azureServiceEndpoint?: string; + azureSttEndpointId?: string; + asrDtmfTerminationDigit?: string; + asrTimeout?: number; + fastRecognitionTimeout?: number; + minConfidence?: number; + nuanceOptions?: NuanceOptions; + deepgramOptions?: DeepgramOptions; + ibmOptions?: IbmOptions; + nvidiaOptions?: NvidiaOptions; + sonioxOptions?: SonioxOptions; + cobaltOptions?: CobaltOptions; + awsOptions?: AwsOptions; + azureOptions?: AzureOptions; + assemblyAiOptions?: AssemblyAiOptions; + googleOptions?: GoogleOptions; + customOptions?: CustomOptions; + verbioOptions?: VerbioOptions; + speechmaticsOptions?: SpeechmaticsOptions; + openaiOptions?: OpenaiOptions; + houndifyOptions?: HoundifyOptions; + gladiaOptions?: Record; + elevenlabsOptions?: ElevenlabsOptions; +} + +interface CallRecord { + path: string; +} + +interface RecordOptions { + action: "startCallRecording" | "stopCallRecording" | "pauseCallRecording" | "resumeCallRecording"; + recordingID?: string; + siprecServerURL?: string | unknown[]; + headers?: Record; +} + +interface Resource { + externalReference?: ResourceReference; + inlineWordset?: string; + builtin?: string; + inlineGrammar?: string; + wakeupWord?: unknown[]; + weightName?: "defaultWeight" | "lowest" | "low" | "medium" | "high" | "highest"; + weightValue?: number; + reuse?: "undefined_reuse" | "low_reuse" | "high_reuse"; +} + +interface ResourceReference { + type?: + | "undefined_resource_type" + | "wordset" + | "compiled_wordset" + | "domain_lm" + | "speaker_profile" + | "grammar" + | "settings"; + uri?: string; + maxLoadFailures?: boolean; + requestTimeoutMs?: number; + headers?: Record; +} + +interface SmAudioEventsConfig { + types?: "applause" | "music" | "laughter"; +} + +interface SmAudioFilteringConfig { + volume_threshold: number; +} + +interface SmPuctuationOverrides { + permitted_marks?: unknown[]; + sensitivity?: number; +} + +interface SmSpeakerDiarizationConfig { + speaker_sensitivity?: number; + max_speakers?: number; +} + +interface SmTranscriptFilteringConfig { + remove_disfluencies: boolean; +} + +interface SmTranscriptionConfig { + language?: string; + domain?: string; + additional_vocab?: unknown[]; + diarization?: string; + speaker_diarization_config?: SmSpeakerDiarizationConfig; + enable_partials?: boolean; + max_delay?: number; + max_delay_mode?: "fixed" | "flexible"; + output_locale?: string; + punctuation_overrides?: SmPuctuationOverrides; + operating_point?: string; + enable_entities?: boolean; + audio_filtering_config?: SmAudioFilteringConfig; + transcript_filtering_config?: SmTranscriptFilteringConfig; +} + +interface SmTranslationConfig { + target_languages: unknown[]; + enable_partials?: boolean; +} + +interface SonioxOptions { + apiKey?: string; + model?: string; + endpointDetection?: boolean; + profanityFilter?: boolean; + speechContext?: string; + clientRequestReference?: string; + storage?: SonioxStorage; +} + +interface SonioxStorage { + id?: string; + title?: string; + disableStoreAudio?: boolean; + disableStoreTranscript?: boolean; + disableSearch?: boolean; + metadata?: Record; +} + +interface SpeechmaticsOptions { + transcription_config?: SmTranscriptionConfig; + translation_config?: SmTranslationConfig; + audio_events_config_config?: SmAudioEventsConfig; +} + +interface Synthesizer { + vendor: string; + label?: string; + language?: string; + voice?: string | Record; + fallbackVendor?: string; + fallbackLabel?: string; + fallbackLanguage?: string; + fallbackVoice?: string | Record; + engine?: "standard" | "neural" | "generative" | "long-form"; + gender?: "MALE" | "FEMALE" | "NEUTRAL"; + options?: Record; +} + +interface Target { + type: "phone" | "sip" | "user" | "teams"; + confirmHook?: Record | string; + method?: "GET" | "POST"; + headers?: Record; + from?: DialFrom; + name?: string; + number?: string; + sipUri?: string; + auth?: Auth; + vmail?: boolean; + tenant?: string; + trunk?: string; + overrideTo?: string; + proxy?: string; +} + +interface TranscribeOptions { + enable: boolean; + transcriptionHook?: string; + recognizer?: Recognizer; +} + +interface TtsStream { + enable: boolean; + synthesizer?: Synthesizer; +} + +interface TurnDetection { + type: "none" | "server_vad" | "semantic_vad"; + eagerness?: "low" | "medium" | "high" | "auto"; + threshold?: number; + prefix_padding_ms?: number; + silence_duration_ms?: number; +} + +interface TurnDetectionPipeline { + vendor: "krisp"; + threshold?: number; + eagerEotThreshold?: number; +} + +interface Vad { + enable?: boolean; + voiceMs?: number; + silenceMs?: number; + strategy?: string; + mode?: number; + vendor?: "webrtc" | "silero"; + threshold?: number; + speechPadMs?: number; +} + +interface VerbioOptions { + enable_formatting?: boolean; + enable_diarization?: boolean; + topic?: number; + inline_grammar?: string; + grammar_uri?: string; + label?: string; + recognition_timeout?: number; + speech_complete_timeout?: number; + speech_incomplete_timeout?: number; +} + +interface Alert { + id?: string; + message: string; +} + +interface Answer { + id?: string; +} + +interface Conference { + id?: string; + name: string; + beep?: boolean; + memberTag?: string; + speakOnlyTo?: string; + startConferenceOnEnter?: boolean; + endConferenceOnExit?: boolean; + endConferenceDuration?: number; + maxParticipants?: number; + joinMuted?: boolean; + actionHook?: Record | string; + waitHook?: Record | string; + statusEvents?: unknown[]; + statusHook?: Record | string; + enterHook?: Record | string; + record?: CallRecord; + distributeDtmf?: boolean; +} + +interface Config { + id?: string; + synthesizer?: Synthesizer; + recognizer?: Recognizer; + bargeIn?: BargeIn; + ttsStream?: TtsStream; + record?: RecordOptions; + listen?: ListenOptions; + stream?: ListenOptions; + transcribe?: TranscribeOptions; + amd?: Amd; + fillerNoise?: FillerNoise; + notifyEvents?: boolean; + notifySttLatency?: boolean; + reset?: string | unknown[]; + onHoldMusic?: string; + actionHookDelayAction?: ActionHookDelayAction; + sipRequestWithinDialogHook?: Record | string; + boostAudioSignal?: number | string; + vad?: Vad; + referHook?: Record | string; + earlyMedia?: boolean; + autoStreamTts?: boolean; + disableTtsCache?: boolean; +} + +interface Dequeue { + id?: string; + name: string; + actionHook?: Record | string; + timeout?: number; + beep?: boolean; + callSid?: string; +} + +interface Dial { + id?: string; + actionHook?: Record | string; + onHoldHook?: Record | string; + answerOnBridge?: boolean; + callerId?: string; + callerName?: string; + confirmHook?: Record | string; + referHook?: Record | string; + dialMusic?: string; + dtmfCapture?: Record; + dtmfHook?: Record | string; + headers?: Record; + anchorMedia?: boolean; + exitMediaPath?: boolean; + boostAudioSignal?: number | string; + listen?: Listen; + stream?: Listen; + target: Target[]; + timeLimit?: number; + timeout?: number; + proxy?: string; + transcribe?: Transcribe; + amd?: Amd; + dub?: Dub[]; + tag?: Record; + forwardPAI?: boolean; +} + +interface Dialogflow { + id?: string; + credentials: Record | string; + project: string; + agent?: string; + environment?: string; + region?: string; + model?: "es" | "cx"; + lang: string; + actionHook?: Record | string; + eventHook?: Record | string; + events?: unknown[]; + welcomeEvent?: string; + welcomeEventParams?: Record; + noInputTimeout?: number; + noInputEvent?: string; + passDtmfAsTextInput?: boolean; + thinkingMusic?: string; + tts?: Synthesizer; + bargein?: boolean; + queryInput?: QueryInput; +} + +interface Dtmf { + id?: string; + dtmf: string; + duration?: number; +} + +interface Dub { + id?: string; + action: "addTrack" | "removeTrack" | "silenceTrack" | "playOnTrack" | "sayOnTrack"; + track: string; + play?: string; + say?: string | Record; + loop?: boolean; + gain?: number | string; +} + +interface Enqueue { + id?: string; + name: string; + actionHook?: Record | string; + waitHook?: Record | string; + priority?: number; + _?: Record; +} + +interface Gather { + id?: string; + actionHook?: Record | string; + finishOnKey?: string; + input?: unknown[]; + numDigits?: number; + minDigits?: number; + maxDigits?: number; + interDigitTimeout?: number; + partialResultHook?: Record | string; + speechTimeout?: number; + listenDuringPrompt?: boolean; + dtmfBargein?: boolean; + bargein?: boolean; + minBargeinWordCount?: number; + timeout?: number; + recognizer?: Recognizer; + play?: Play; + say?: Say; + fillerNoise?: FillerNoise; + actionHookDelayAction?: ActionHookDelayAction; +} + +interface Hangup { + id?: string; + headers?: Record; +} + +interface Leave { + id?: string; +} + +interface Lex { + id?: string; + botId: string; + botAlias: string; + credentials: Record; + region: string; + locale?: string; + intent?: LexIntent; + welcomeMessage?: string; + metadata?: Record; + bargein?: boolean; + passDtmf?: boolean; + actionHook?: Record | string; + eventHook?: Record | string; + noInputTimeout?: number; + tts?: Synthesizer; +} + +interface Listen { + id?: string; + actionHook?: Record | string; + auth?: Auth; + finishOnKey?: string; + maxLength?: number; + metadata?: Record; + mixType?: "mono" | "stereo" | "mixed"; + passDtmf?: boolean; + playBeep?: boolean; + disableBidirectionalAudio?: boolean; + bidirectionalAudio?: BidirectionalAudio; + sampleRate?: number; + timeout?: number; + transcribe?: Transcribe; + url: string; + wsAuth?: Auth; + earlyMedia?: boolean; + channel?: number; +} + +interface Llm { + id?: string; + vendor: string; + model?: string; + auth?: Record; + connectOptions?: Record; + mcpServers?: McpServer[]; + actionHook?: Record | string; + eventHook?: Record | string; + toolHook?: Record | string; + events?: unknown[]; + llmOptions: Record; +} + +interface Message { + id?: string; + carrier?: string; + account_sid?: string; + message_sid?: string; + to: string; + from: string; + text?: string; + media?: string | unknown[]; + actionHook?: Record | string; +} + +interface Pause { + id?: string; + length: number; +} + +interface Pipeline { + id?: string; + stt: Recognizer; + tts: Synthesizer; + vad?: Vad; + turnDetection?: TurnDetectionPipeline; + llm: Llm; + preflightLlm?: boolean; + actionHook?: Record | string; + eventHook?: Record | string; +} + +interface Play { + id?: string; + url: string | unknown[]; + loop?: number | string; + earlyMedia?: boolean; + seekOffset?: number | string; + timeoutSecs?: number | string; + actionHook?: Record | string; +} + +interface Rasa { + id?: string; + url: string; + recognizer?: Recognizer; + tts?: Synthesizer; + prompt?: string; + actionHook?: Record | string; + eventHook?: Record | string; +} + +interface Redirect { + id?: string; + actionHook: Record | string; +} + +interface RestDial { + id?: string; + account_sid?: string; + application_sid?: string; + call_hook: Record | string; + call_status_hook?: Record | string; + from: string; + callerName?: string; + fromHost?: string; + speech_synthesis_vendor?: string; + speech_synthesis_voice?: string; + speech_synthesis_language?: string; + speech_recognizer_vendor?: string; + speech_recognizer_language?: string; + tag?: Record; + to: Target; + headers?: Record; + timeout?: number; + amd?: Amd; + dual_streams?: boolean; + sipRequestWithinDialogHook?: string; + referHook?: Record | string; + timeLimit?: number; +} + +interface Say { + id?: string; + text?: string | unknown[]; + instructions?: string; + stream?: boolean; + loop?: number | string; + synthesizer?: Synthesizer; + earlyMedia?: boolean; + disableTtsCache?: boolean; + closeStreamOnEmpty?: boolean; +} + +interface SipDecline { + id?: string; + status: number; + reason?: string; + headers?: Record; +} + +interface SipRefer { + id?: string; + referTo: string; + referredBy?: string; + referredByDisplayName?: string; + headers?: Record; + actionHook?: Record | string; + eventHook?: Record | string; +} + +interface SipRequest { + id?: string; + method: string; + body?: string; + headers?: Record; + actionHook?: Record | string; +} + +interface Stream { + id?: string; + actionHook?: Record | string; + auth?: Auth; + finishOnKey?: string; + maxLength?: number; + metadata?: Record; + mixType?: "mono" | "stereo" | "mixed"; + passDtmf?: boolean; + playBeep?: boolean; + disableBidirectionalAudio?: boolean; + bidirectionalAudio?: BidirectionalAudio; + sampleRate?: number; + timeout?: number; + transcribe?: Transcribe; + url: string; + wsAuth?: Auth; + earlyMedia?: boolean; +} + +interface Tag { + id?: string; + data: Record; +} + +interface Transcribe { + id?: string; + transcriptionHook?: string; + translationHook?: string; + recognizer?: Recognizer; + earlyMedia?: boolean; + channel?: number; +} + +// ============================================ +// REST API Types (from calls.yaml + platform.yaml) +// ============================================ + +interface JambonzOptions { + baseUrl: string; +} + +interface Webhook { + webhook_sid?: string; + url: string; + method?: "get" | "post"; + username?: string; + password?: string; +} + +interface ApiTarget { + type: "phone" | "sip" | "user" | "teams"; + number?: string; + sipUri?: string; + /** Microsoft Teams customer tenant domain name */ + tenant?: string; + trunk?: string; + /** Dial directly into user's voicemail to leave a message */ + vmail?: boolean; + overrideTo?: string; + name?: string; + auth?: { + username?: string; + password?: string; + }; +} + +interface ApiCall { + account_sid: string; + application_sid?: string; + call_id: string; + call_sid: string; + call_status: + | "trying" + | "ringing" + | "alerting" + | "in-progress" + | "completed" + | "busy" + | "no-answer" + | "failed" + | "queued"; + caller_name?: string; + direction: "inbound" | "outbound"; + duration?: number; + from: string; + originating_sip_trunk_name?: string; + parent_call_sid?: string; + service_url: string; + sip_status: number; + to: string; +} + +interface ApiApplication { + application_sid?: string; + name: string; + account_sid: string; + /** application webhook for inbound voice calls */ + call_hook?: Webhook; + /** webhhok for reporting call status events */ + call_status_hook?: Webhook; + /** application webhook for inbound SMS/MMS */ + messaging_hook?: Webhook; + speech_synthesis_vendor?: string; + speech_synthesis_voice?: string; + speech_recognizer_vendor?: string; + speech_recognizer_language?: string; + /** Object containing the Application Environment Variables as key/value to be sent with the call_hook payload */ + env_vars?: Record; + record_all_calls?: boolean; +} + +interface ApiMessage { + provider?: string; + from: string; + to: string; + text?: string; + media?: string; +} + +interface Account { + account_sid: string; + name: string; + sip_realm?: string; + /** authentication webhook for registration */ + registration_hook?: Webhook; + device_calling_application_sid?: string; + service_provider_sid: string; + record_all_calls?: boolean; + record_format?: "wav" | "mp3"; + /** Credentials for recording storage */ + bucket_credential?: { + vendor?: "aws_s3" | "s3_compatible" | "azure" | "google"; + region?: string; + /** name of the bucket */ + name?: string; + access_key_id?: string; + secret_access_key?: string; + }; +} + +interface VoipCarrier { + service_provider_sid: string; + name: string; + description?: string; + account_sid?: string; + application_sid?: string; + e164_leading_plus?: boolean; + requires_register?: boolean; + register_username?: string; + register_sip_realm?: string; + register_password?: string; + tech_prefix?: string; + diversion?: string; + is_active?: boolean; + smpp_system_id?: string; + smpp_password?: string; + smpp_inbound_system_id?: string; + smpp_inbound_password?: string; + smpp_enquire_link_interval?: number; + /** The type of trunk to create, see the [guide](/guides/using-the-jambonz-portal/basic-concepts/creating-carriers) for details */ + trunk_type?: "static_ip" | "auth" | "reg"; + /** username for an auth trunk */ + inbound_auth_username?: string; + /** password for an auth trunk */ + inbound_auth_password?: string; +} + +interface SipGateway { + sip_gateway_sid: string; + ipv4: string; + port: number; + netmask: number; + voip_carrier_sid: string; + inbound?: boolean; + outbound?: boolean; +} + +interface SmppGateway { + smpp_gateway_sid: string; + ipv4: string; + port: number; + netmask: number; + voip_carrier_sid: string; + is_primary?: boolean; + use_tls?: boolean; + inbound?: boolean; + outbound?: boolean; +} + +interface PhoneNumber { + phone_number_sid: string; + number: string; + voip_carrier_sid: string; + account_sid?: string; + application_sid?: string; +} + +interface SpeechCredential { + speech_credential_sid?: string; + account_sid?: string; + vendor?: "google" | "aws"; + service_key?: string; + access_key_id?: string; + secret_access_key?: string; + aws_region?: string; + last_used?: string; + last_tested?: string; + use_for_tts?: boolean; + use_for_stt?: boolean; + tts_tested_ok?: boolean; + stt_tested_ok?: boolean; + riva_server_uri?: string; +} + +interface ServiceProvider { + service_provider_sid: string; + name: string; + description?: string; + root_domain?: string; + /** authentication webhook for registration */ + registration_hook?: Webhook; + ms_teams_fqdn?: string; + /** used for inbound testing for accounts on free plan */ + test_number?: string; + /** name of test application that can be used for new signups */ + test_application_name?: string; + /** identifies test application that can be used for new signups */ + test_application_sid?: string; +} + +interface Registration { + registration_sid: string; + username: string; + domain: string; + sip_contact: string; + sip_user_agent?: string; +} + +interface ApiKey { + api_key_sid: string; + token: string; + account_sid?: string; + service_provider_sid?: string; + expires_at?: string; + created_at?: string; + last_used?: string; +} + +interface GeneralError { + msg: string; +} + +interface CreateCallOptions { + /** The application to use to control this call. Either application_sid or call_hook is required. */ + application_sid?: string; + /** If set to true, the inbound call will ring until the number that was dialed answers the call, and at that point a 200 OK will be sent on the inbound leg. If false, the inbound call will be answered immediately as the outbound call is placed. */ + answerOnBridge?: boolean; + call_hook?: Webhook; + call_status_hook?: Webhook; + /** The calling party number */ + from: string; + /** The hostname to put in the SIP From header of the INVITE */ + fromHost?: string; + /** The number of seconds to wait for call to be answered. Defaults to 60. */ + timeout?: number; + /** The max length of call in seconds */ + timeLimit?: number; + /** Initial set of customer-supplied metadata to associate with the call (see jambonz 'tag' verb) */ + tag?: Record; + /** Destination for call */ + to: ApiTarget; + /** The customer SIP headers to associate with the call */ + headers?: Record; + /** The sip indialog hook to receive session messages */ + sipRequestWithinDialogHook?: string; + /** The vendor for Text to Speech (required if application_sid is not used) */ + speech_synthesis_vendor?: string; + /** The language for Text to Speech (required if application_sid is not used) */ + speech_synthesis_language?: string; + /** The voice for Text to Speech (required if application_sid is not used) */ + speech_synthesis_voice?: string; + /** The vendor for Speech to Text (required if application_sid is not used) */ + speech_recognizer_vendor?: string; + /** The language for Speech to Text (required if application_sid is not used) */ + speech_recognizer_language?: string; + amd?: Amd; +} + +interface UpdateCallOptions { + call_hook?: Webhook; + child_call_hook?: Webhook; + call_status?: "completed" | "no-answer"; + conf_mute_status?: "mute" | "unmute"; + conf_hold_status?: "hold" | "unhold"; + listen_status?: "pause" | "silence" | "resume"; + mute_status?: "mute" | "unmute"; + transcribe_status?: "pause" | "resume"; + whisper?: { + /** See [Say](/verbs/verbs/say) or [Play](/verbs/verbs/play) for details of the properties */ + verb?: "say" | "play"; + } | { + /** See [Say](/verbs/verbs/say) or [Play](/verbs/verbs/play) for details of the properties */ + verb?: "say" | "play"; + }[]; + sip_request?: { + method?: string; + content_type?: string; + content?: string; + headers?: Record; + }; + record?: { + action?: "startCallRecording" | "stopCallRecording" | "pauseCallRecording" | "resumeCallRecording"; + recordingID?: string; + siprecServerURL?: string; + }; + conferenceParticipantAction?: { + action?: "tag" | "untag" | "coach" | "uncoach" | "mute" | "unmute" | "hold" | "unhold"; + tag?: string; + }; + dtmf?: { + /** Single digit to send */ + digit: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" | "*" | "#"; + /** Duration of the tone in ms */ + duration?: number; + }; +} + +interface CreateApplicationOptions { + /** application name */ + name: string; + account_sid: string; + /** application webhook to handle inbound voice calls */ + call_hook: Webhook; + /** webhook to report call status events */ + call_status_hook: Webhook; + /** application webhook to handle inbound SMS/MMS messages */ + messaging_hook?: Webhook; + /** Voice Application Json, call_hook will not be invoked if app_json is provided */ + app_json?: string; + speech_synthesis_vendor?: string; + speech_synthesis_voice?: string; + speech_recognizer_vendor?: string; + speech_recognizer_language?: string; + /** Object containing the Application Environment Variables as key/value to be sent with the call_hook payload */ + env_vars?: Record; +} + +interface UpdateApplicationOptions { + application_sid?: string; + name: string; + account_sid: string; + /** application webhook for inbound voice calls */ + call_hook?: Webhook; + /** webhhok for reporting call status events */ + call_status_hook?: Webhook; + /** application webhook for inbound SMS/MMS */ + messaging_hook?: Webhook; + speech_synthesis_vendor?: string; + speech_synthesis_voice?: string; + speech_recognizer_vendor?: string; + speech_recognizer_language?: string; + /** Object containing the Application Environment Variables as key/value to be sent with the call_hook payload */ + env_vars?: Record; + record_all_calls?: boolean; +} + +interface CreateMessageOptions { + provider?: string; + from: string; + to: string; + text?: string; + media?: string; +} + +// ============================================ +// Classes +// ============================================ + +declare class Calls { + create(opts: CreateCallOptions): Promise; + update(callSid: string, opts: UpdateCallOptions): Promise; + list(opts?: Record): Promise; + retrieve(callSid: string): Promise; + delete(callSid: string): Promise; +} + +declare class Messages { + create(opts: CreateMessageOptions): Promise; +} + +declare class Applications { + create(opts: CreateApplicationOptions): Promise; + update(appSid: string, opts: UpdateApplicationOptions): Promise; + list(opts?: Record): Promise; + retrieve(appSid: string): Promise; + delete(appSid: string): Promise; +} + +declare class Jambonz { + constructor(accountSid: string, apiKey: string, opts: JambonzOptions); + calls: Calls; + messages: Messages; + applications: Applications; +} + +declare class WebhookResponse { + payload: object[]; + length: number; + + constructor(); + + static verifyJambonzSignature( + secret: string | string[], + ): (req: unknown, res: unknown, next: () => void) => void; + + toJSON(): object[]; + + // Verb methods + alert(payload: Alert): this; + answer(payload?: Answer): this; + sip_decline(payload: SipDecline): this; + sip_request(payload: SipRequest): this; + sip_refer(payload: SipRefer): this; + config(payload?: Config): this; + dub(payload: Dub): this; + dequeue(payload: Dequeue): this; + enqueue(payload: Enqueue): this; + leave(payload?: Leave): this; + hangup(payload?: Hangup): this; + play(payload: Play): this; + say(payload?: Say): this; + gather(payload?: Gather): this; + conference(payload: Conference): this; + dial(payload: Dial): this; + dialogflow(payload: Dialogflow): this; + dtmf(payload: Dtmf): this; + lex(payload: Lex): this; + listen(payload: Listen): this; + stream(payload: Stream): this; + llm(payload: Llm): this; + message(payload: Message): this; + pause(payload: Pause): this; + rasa(payload: Rasa): this; + redirect(payload: Redirect): this; + rest_dial(payload: RestDial): this; + tag(payload: Tag): this; + transcribe(payload?: Transcribe): this; + pipeline(payload: Pipeline): this; +} + +// ============================================ +// Main Export (DefinitelyTyped format) +// ============================================ + +declare function jambonz(accountSid: string, apiKey: string, opts: JambonzOptions): Jambonz; + +declare namespace jambonz { + export { + Account, + ActionHookDelayAction, + Alert, + Amd, + AmdTimers, + Answer, + ApiApplication, + ApiCall, + ApiKey, + ApiMessage, + ApiTarget, + Applications, + AssemblyAiOptions, + Auth, + AwsOptions, + AzureOptions, + BargeIn, + BidirectionalAudio, + CallRecord, + Calls, + CobaltOptions, + Conference, + Config, + CreateApplicationOptions, + CreateCallOptions, + CreateMessageOptions, + CustomOptions, + DeepgramOptions, + Dequeue, + Dial, + DialFrom, + Dialogflow, + Dtmf, + Dub, + ElevenlabsOptions, + Enqueue, + FillerNoise, + Formatting, + Gather, + GeneralError, + GoogleOptions, + Hangup, + HoundifyOptions, + IbmOptions, + Jambonz, + JambonzOptions, + Leave, + Lex, + LexIntent, + Listen, + ListenOptions, + Llm, + McpServer, + Message, + Messages, + NuanceOptions, + NvidiaOptions, + OpenaiOptions, + Pause, + PhoneNumber, + Pipeline, + Play, + PromptTemplates, + QueryInput, + Rasa, + Recognizer, + RecordOptions, + Redirect, + Registration, + Resource, + ResourceReference, + RestDial, + Say, + ServiceProvider, + SipDecline, + SipGateway, + SipRefer, + SipRequest, + SmAudioEventsConfig, + SmAudioFilteringConfig, + SmppGateway, + SmPuctuationOverrides, + SmSpeakerDiarizationConfig, + SmTranscriptFilteringConfig, + SmTranscriptionConfig, + SmTranslationConfig, + SonioxOptions, + SonioxStorage, + SpeechCredential, + SpeechmaticsOptions, + Stream, + Synthesizer, + Tag, + Target, + Transcribe, + TranscribeOptions, + TtsStream, + TurnDetection, + TurnDetectionPipeline, + UpdateApplicationOptions, + UpdateCallOptions, + Vad, + VerbioOptions, + VoipCarrier, + Webhook, + WebhookResponse, + }; +} + +export = jambonz; diff --git a/types/jambonz__node-client/jambonz__node-client-tests.ts b/types/jambonz__node-client/jambonz__node-client-tests.ts new file mode 100644 index 00000000000000..739c8b5e622735 --- /dev/null +++ b/types/jambonz__node-client/jambonz__node-client-tests.ts @@ -0,0 +1,379 @@ +import jambonz = require("@jambonz/node-client"); + +// Test main client instantiation +const client = jambonz("account-sid", "api-key", { baseUrl: "https://api.jambonz.us" }); + +// $ExpectType Calls +client.calls; + +// $ExpectType Messages +client.messages; + +// $ExpectType Applications +client.applications; + +// Test WebhookResponse +const response = new jambonz.WebhookResponse(); + +// $ExpectType WebhookResponse +response.say({ text: "Hello" }).gather({ input: ["speech"] }).hangup(); + +// $ExpectType object[] +response.toJSON(); + +// Test type imports work +const callOpts: jambonz.CreateCallOptions = { + from: "+15551234567", + to: { type: "phone", number: "+15559876543" }, + call_hook: { url: "https://example.com/webhook" }, +}; + +const sayPayload: jambonz.Say = { + text: "Hello world", +}; + +const recognizer: jambonz.Recognizer = { + vendor: "google", + language: "en-US", +}; + +// @ts-expect-error - missing required 'from' field +const badCallOpts: jambonz.CreateCallOptions = { + to: { type: "phone", number: "+15559876543" }, +}; + +// @ts-expect-error - missing required 'name' field +const badConference: jambonz.Conference = { + id: "123", +}; + +// Test static method +const middleware = jambonz.WebhookResponse.verifyJambonzSignature("secret"); + +// Test Calls class methods +async function testCalls() { + // $ExpectType Promise + client.calls.create({ + from: "+15551234567", + to: { type: "phone", number: "+15559876543" }, + call_hook: { url: "https://example.com/webhook" }, + }); + + // $ExpectType Promise + client.calls.update("call-sid", { call_status: "completed" }); + + // $ExpectType Promise + client.calls.list(); + + // $ExpectType Promise + client.calls.retrieve("call-sid"); + + // $ExpectType Promise + client.calls.delete("call-sid"); +} + +// Test Messages class methods +async function testMessages() { + // $ExpectType Promise + client.messages.create({ + from: "+15551234567", + to: "+15559876543", + text: "Hello!", + }); +} + +// Test Applications class methods +async function testApplications() { + // $ExpectType Promise + client.applications.create({ + name: "Test App", + account_sid: "account-sid", + call_hook: { url: "https://example.com/call" }, + call_status_hook: { url: "https://example.com/status" }, + }); + + // $ExpectType Promise + client.applications.update("app-sid", { + name: "Updated App", + account_sid: "account-sid", + }); + + // $ExpectType Promise + client.applications.list(); + + // $ExpectType Promise + client.applications.retrieve("app-sid"); + + // $ExpectType Promise + client.applications.delete("app-sid"); +} + +// Test WebhookResponse verb chaining +const verbChainResponse = new jambonz.WebhookResponse() + .answer() + .config({ synthesizer: { vendor: "google", language: "en-US", voice: "en-US-Wavenet-A" } }) + .say({ text: "Welcome to the call" }) + .gather({ + input: ["speech", "dtmf"], + actionHook: "https://example.com/gather", + recognizer: { vendor: "google", language: "en-US" }, + }) + .pause({ length: 2 }) + .play({ url: "https://example.com/audio.mp3" }) + .hangup(); + +// Test dial verb with targets +const dialResponse = new jambonz.WebhookResponse().dial({ + target: [ + { type: "phone", number: "+15559876543" }, + { type: "sip", sipUri: "sip:user@example.com" }, + { type: "user", name: "john" }, + ], + timeout: 30, + timeLimit: 3600, + actionHook: "https://example.com/dial-action", +}); + +// Test conference verb +const conferenceResponse = new jambonz.WebhookResponse().conference({ + name: "my-conference", + beep: true, + startConferenceOnEnter: true, + endConferenceOnExit: false, + maxParticipants: 10, +}); + +// Test listen verb +const listenResponse = new jambonz.WebhookResponse().listen({ + url: "wss://example.com/audio-stream", + mixType: "stereo", + sampleRate: 16000, +}); + +// Test stream verb +const streamResponse = new jambonz.WebhookResponse().stream({ + url: "wss://example.com/stream", + bidirectionalAudio: { enabled: true, streaming: true }, +}); + +// Test llm verb +const llmResponse = new jambonz.WebhookResponse().llm({ + vendor: "openai", + model: "gpt-4", + llmOptions: { temperature: 0.7 }, + actionHook: "https://example.com/llm-action", +}); + +// Test pipeline verb +const pipelineResponse = new jambonz.WebhookResponse().pipeline({ + stt: { vendor: "google", language: "en-US" }, + tts: { vendor: "google", language: "en-US", voice: "en-US-Wavenet-A" }, + llm: { vendor: "openai", llmOptions: { model: "gpt-4" } }, +}); + +// Test dialogflow verb +const dialogflowResponse = new jambonz.WebhookResponse().dialogflow({ + credentials: { client_email: "test@example.com", private_key: "key" }, + project: "my-project", + lang: "en-US", +}); + +// Test lex verb +const lexResponse = new jambonz.WebhookResponse().lex({ + botId: "bot-123", + botAlias: "prod", + credentials: { accessKeyId: "key", secretAccessKey: "secret" }, + region: "us-east-1", +}); + +// Test message verb +const messageResponse = new jambonz.WebhookResponse().message({ + from: "+15551234567", + to: "+15559876543", + text: "Hello from the call!", +}); + +// Test enqueue/dequeue verbs +const enqueueResponse = new jambonz.WebhookResponse().enqueue({ + name: "support-queue", + waitHook: "https://example.com/wait", +}); + +const dequeueResponse = new jambonz.WebhookResponse().dequeue({ + name: "support-queue", + actionHook: "https://example.com/dequeue-action", +}); + +// Test sip verbs +const sipDeclineResponse = new jambonz.WebhookResponse().sip_decline({ + status: 486, + reason: "Busy Here", +}); + +const sipReferResponse = new jambonz.WebhookResponse().sip_refer({ + referTo: "sip:user@example.com", +}); + +const sipRequestResponse = new jambonz.WebhookResponse().sip_request({ + method: "INFO", + body: "Signal=5", +}); + +// Test dub verb +const dubResponse = new jambonz.WebhookResponse().dub({ + action: "addTrack", + track: "background-music", + play: "https://example.com/music.mp3", + loop: true, +}); + +// Test dtmf verb +const dtmfResponse = new jambonz.WebhookResponse().dtmf({ + dtmf: "1234#", + duration: 250, +}); + +// Test tag verb +const tagResponse = new jambonz.WebhookResponse().tag({ + data: { customerId: "12345", priority: "high" }, +}); + +// Test transcribe verb +const transcribeResponse = new jambonz.WebhookResponse().transcribe({ + transcriptionHook: "https://example.com/transcribe", + recognizer: { vendor: "google", language: "en-US" }, +}); + +// Test redirect verb +const redirectResponse = new jambonz.WebhookResponse().redirect({ + actionHook: "https://example.com/new-handler", +}); + +// Test alert verb +const alertResponse = new jambonz.WebhookResponse().alert({ + message: "Important notification", +}); + +// Test leave verb +const leaveResponse = new jambonz.WebhookResponse().leave(); + +// Test rasa verb +const rasaResponse = new jambonz.WebhookResponse().rasa({ + url: "https://rasa.example.com/webhooks/rest/webhook", + prompt: "Hello", +}); + +// Test rest_dial verb +const restDialResponse = new jambonz.WebhookResponse().rest_dial({ + from: "+15551234567", + to: { type: "phone", number: "+15559876543" }, + call_hook: "https://example.com/call", +}); + +// Test various type interfaces +const synthesizer: jambonz.Synthesizer = { + vendor: "google", + language: "en-US", + voice: "en-US-Wavenet-A", + engine: "neural", +}; + +const target: jambonz.Target = { + type: "phone", + number: "+15559876543", + confirmHook: "https://example.com/confirm", +}; + +const webhook: jambonz.Webhook = { + url: "https://example.com/webhook", + method: "post", + username: "user", + password: "pass", +}; + +const vad: jambonz.Vad = { + enable: true, + voiceMs: 250, + silenceMs: 500, + vendor: "silero", + threshold: 0.5, +}; + +const bargeIn: jambonz.BargeIn = { + enable: true, + sticky: true, + input: ["speech", "dtmf"], + minBargeinWordCount: 2, +}; + +const deepgramOptions: jambonz.DeepgramOptions = { + model: "nova-2", + punctuate: true, + smartFormatting: true, + diarize: true, +}; + +const awsOptions: jambonz.AwsOptions = { + region: "us-east-1", + vocabularyName: "custom-vocab", +}; + +const googleOptions: jambonz.GoogleOptions = { + serviceVersion: "v2", + enableVoiceActivityEvents: true, +}; + +// Test API types +const apiCall: jambonz.ApiCall = { + account_sid: "account-123", + call_id: "call-id-123", + call_sid: "call-sid-123", + call_status: "in-progress", + direction: "outbound", + from: "+15551234567", + to: "+15559876543", + service_url: "https://example.com", + sip_status: 200, +}; + +const apiApplication: jambonz.ApiApplication = { + name: "My App", + account_sid: "account-123", + call_hook: { url: "https://example.com/call" }, + speech_synthesis_vendor: "google", + speech_recognizer_vendor: "google", +}; + +const account: jambonz.Account = { + account_sid: "account-123", + name: "My Account", + service_provider_sid: "sp-123", +}; + +const voipCarrier: jambonz.VoipCarrier = { + service_provider_sid: "sp-123", + name: "My Carrier", + trunk_type: "static_ip", +}; + +// Test UpdateCallOptions +const updateOpts: jambonz.UpdateCallOptions = { + call_status: "completed", + mute_status: "mute", + whisper: { verb: "say" }, +}; + +// @ts-expect-error - missing required 'name' field for CreateApplicationOptions +const badAppOpts: jambonz.CreateApplicationOptions = { + account_sid: "account-123", + call_hook: { url: "https://example.com/call" }, + call_status_hook: { url: "https://example.com/status" }, +}; + +// @ts-expect-error - missing required 'to' and 'from' fields +const badMessageOpts: jambonz.CreateMessageOptions = { + text: "Hello", +}; + +// Test verifyJambonzSignature with array of secrets +const multiSecretMiddleware = jambonz.WebhookResponse.verifyJambonzSignature(["secret1", "secret2"]); diff --git a/types/jambonz__node-client/package.json b/types/jambonz__node-client/package.json new file mode 100644 index 00000000000000..693ad48868bf5e --- /dev/null +++ b/types/jambonz__node-client/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "name": "@types/jambonz__node-client", + "version": "0.4.9999", + "projects": [ + "https://github.com/jambonz/jambonz-node" + ], + "devDependencies": { + "@types/jambonz__node-client": "workspace:." + }, + "owners": [ + { + "name": "Jacob Owens", + "githubUsername": "BuckyMcYolo" + } + ] +} diff --git a/types/jambonz__node-client/tsconfig.json b/types/jambonz__node-client/tsconfig.json new file mode 100644 index 00000000000000..7c131585c06440 --- /dev/null +++ b/types/jambonz__node-client/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "node16", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "jambonz__node-client-tests.ts" + ] +}