Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update createDialer/createPlaylist Interface #517

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/thick-starfishes-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@sw-internal/playground-realtime-api': patch
'@signalwire/core': patch
'@signalwire/realtime-api': patch
---

Migrate `createDialer` and `createPlaylist` to Dialer and Playlist constructors
48 changes: 29 additions & 19 deletions internal/playground-realtime-api/src/voice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ async function run() {
})

try {
// Using createDialer util
// const dialer = Voice.createDialer().addPhone({
// to: process.env.TO_NUMBER as string,
// from: process.env.FROM_NUMBER as string,
// timeout: 30,
// })
// Using "new Voice.Dialer" API
// const dialer = new Voice.Dialer().add(
// Voice.Dialer.Phone({
// to: process.env.TO_NUMBER as string,
// from: process.env.FROM_NUMBER as string,
// timeout: 30,
// })
// )
// const call = await client.dial(dialer)

// Using dialPhone Alias
Expand Down Expand Up @@ -111,9 +113,11 @@ async function run() {
// Wait until Main and Peer are connected
await call.waitUntilConnected()

const playlist = Voice.createPlaylist({ volume: 2 }).playTTS({
text: 'Thank you, you are now disconnected from the peer',
})
const playlist = new Voice.Playlist({ volume: 2 }).add(
Voice.Playlist.TTS({
text: 'Thank you, you are now disconnected from the peer',
})
)
await call.play(playlist)

await sleep()
Expand Down Expand Up @@ -217,16 +221,22 @@ async function run() {
console.log('>> playback.ended', p.id, p.state)
})

const playlist = Voice.createPlaylist({ volume: 2 })
.playAudio({
url: 'https://cdn.signalwire.com/default-music/welcome.mp3',
})
.playSilence({
duration: 5,
})
.playTTS({
text: 'Thank you, you are now disconnected from the peer',
})
const playlist = new Voice.Playlist({ volume: 2 })
.add(
Voice.Playlist.Audio({
url: 'https://cdn.signalwire.com/default-music/welcome.mp3',
})
)
.add(
Voice.Playlist.Silence({
duration: 5,
})
)
.add(
Voice.Playlist.TTS({
text: 'Thank you, you are now disconnected from the peer',
})
)
const playback = await call.play(playlist)

console.log('Playback STARTED!', playback.id)
Expand Down
9 changes: 2 additions & 7 deletions packages/core/src/types/voiceCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,7 @@ export interface CreateVoiceDialerParams {

export interface VoiceDialer extends CreateVoiceDialerParams {
devices: VoiceCallDialMethodParams['devices']
addPhone(params: VoiceCallDialPhoneMethodParams): this
addSip(params: VoiceCallDialSipMethodParams): this
inParallel(dialer: VoiceDialer): this
add(params: VoiceCallDeviceParams | VoiceCallDeviceParams[]): this
}

export interface CreateVoicePlaylistParams {
Expand All @@ -356,10 +354,7 @@ export interface CreateVoicePlaylistParams {

export interface VoicePlaylist extends CreateVoicePlaylistParams {
media: VoiceCallPlayMethodParams['media']
playAudio(params: VoiceCallPlayAudioMethodParams): this
playTTS(params: VoiceCallPlayTTSMethodParams): this
playSilence(params: VoiceCallPlaySilenceMethodParams): this
playRingtone(params: VoiceCallPlayRingtoneMethodParams): this
add(params: VoiceCallPlayParams): this
}

/**
Expand Down
15 changes: 6 additions & 9 deletions packages/realtime-api/src/voice/Call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ import {
} from '@signalwire/core'
import { RealTimeCallApiEvents } from '../types'
import { AutoApplyTransformsConsumer } from '../AutoApplyTransformsConsumer'
import {
toInternalDevices,
toInternalPlayParams,
createPlaylist,
} from './utils'
import { toInternalDevices, toInternalPlayParams } from './utils'
import { Playlist } from './Playlist'
import {
voiceCallStateWorker,
voiceCallPlayWorker,
Expand Down Expand Up @@ -467,24 +464,24 @@ export class CallConsumer extends AutoApplyTransformsConsumer<RealTimeCallApiEve

playAudio(params: VoiceCallPlayAudioMethodParams) {
const { volume, ...rest } = params
const playlist = createPlaylist({ volume }).playAudio(rest)
const playlist = new Playlist({ volume }).add(Playlist.Audio(rest))
return this.play(playlist)
}

playSilence(params: VoiceCallPlaySilenceMethodParams) {
const playlist = createPlaylist().playSilence(params)
const playlist = new Playlist().add(Playlist.Silence(params))
return this.play(playlist)
}

playRingtone(params: VoiceCallPlayRingtoneMethodParams) {
const { volume, ...rest } = params
const playlist = createPlaylist({ volume }).playRingtone(rest)
const playlist = new Playlist({ volume }).add(Playlist.Ringtone(rest))
return this.play(playlist)
}

playTTS(params: VoiceCallPlayTTSMethodParams) {
const { volume, ...rest } = params
const playlist = createPlaylist({ volume }).playTTS(rest)
const playlist = new Playlist({ volume }).add(Playlist.TTS(rest))
return this.play(playlist)
}

Expand Down
87 changes: 87 additions & 0 deletions packages/realtime-api/src/voice/Dialer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Dialer } from './Dialer'

describe('Dialer', () => {
it('should build a list of devices to dial', () => {
const dialer = new Dialer()

dialer
.add(Dialer.Phone({ from: '+1', to: '+2', timeout: 30 }))
.add(
Dialer.Sip({
from: 'sip:one',
to: 'sip:two',
headers: [{ name: 'foo', value: 'bar' }],
})
)
.add([
Dialer.Phone({ from: '+3', to: '+4' }),
Dialer.Sip({
from: 'sip:three',
to: 'sip:four',
headers: [{ name: 'baz', value: 'qux' }],
}),
Dialer.Phone({ from: '+5', to: '+6' }),
])

expect(dialer.devices).toStrictEqual([
[
{
type: 'phone',
from: '+1',
to: '+2',
timeout: 30,
},
],
[
{
type: 'sip',
from: 'sip:one',
to: 'sip:two',
headers: [{ name: 'foo', value: 'bar' }],
},
],
[
{
type: 'phone',
from: '+3',
to: '+4',
},
{
type: 'sip',
from: 'sip:three',
to: 'sip:four',
headers: [{ name: 'baz', value: 'qux' }],
},
{
type: 'phone',
from: '+5',
to: '+6',
},
],
])
})

it('should build a list of devices to dial including region', () => {
const dialer = new Dialer({ region: 'us' })
dialer.add([
Dialer.Phone({ from: '+3', to: '+4' }),
Dialer.Phone({ from: '+5', to: '+6' }),
])

expect(dialer.region).toBe('us')
expect(dialer.devices).toStrictEqual([
[
{
type: 'phone',
from: '+3',
to: '+4',
},
{
type: 'phone',
from: '+5',
to: '+6',
},
],
])
})
})
41 changes: 41 additions & 0 deletions packages/realtime-api/src/voice/Dialer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type {
CreateVoiceDialerParams,
VoiceDialer,
VoiceCallDeviceParams,
VoiceCallPhoneParams,
VoiceCallDialPhoneMethodParams,
VoiceCallSipParams,
VoiceCallDialSipMethodParams,
} from '@signalwire/core'

export class Dialer implements VoiceDialer {
private _devices: VoiceDialer['devices'] = []

constructor(private params: CreateVoiceDialerParams = {}) {}

get region() {
return this.params?.region
}

get devices() {
return this._devices
}

add(params: VoiceCallDeviceParams | VoiceCallDeviceParams[]) {
if (Array.isArray(params)) {
this._devices.push(params)
} else {
this._devices.push([params])
}

return this
}

static Phone(params: VoiceCallDialPhoneMethodParams): VoiceCallPhoneParams {
return { type: 'phone', ...params }
}

static Sip(params: VoiceCallDialSipMethodParams): VoiceCallSipParams {
return { type: 'sip', ...params }
}
}
58 changes: 58 additions & 0 deletions packages/realtime-api/src/voice/Playlist.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Playlist } from './Playlist'

describe('Playlist', () => {
it('should build a list of devices to dial', () => {
const playlist = new Playlist()
playlist.add(Playlist.Audio({ url: 'https://example.com/hello.mp3' }))
playlist.add(Playlist.Silence({ duration: 5 }))
playlist.add(Playlist.TTS({ text: 'Hello World' }))
playlist.add(Playlist.Ringtone({ name: 'us' }))
playlist.add(Playlist.Audio({ url: 'https://example.com/hello2.mp3' }))

expect(playlist.media).toStrictEqual([
{
type: 'audio',
url: 'https://example.com/hello.mp3',
},
{
type: 'silence',
duration: 5,
},
{
type: 'tts',
text: 'Hello World',
},
{
type: 'ringtone',
name: 'us',
},
{
type: 'audio',
url: 'https://example.com/hello2.mp3',
},
])
})

it('should build a list of devices to dial including volume', () => {
const playlist = new Playlist({ volume: 2 })
playlist.add(Playlist.Audio({ url: 'https://example.com/hello.mp3' }))
playlist.add(Playlist.Silence({ duration: 5 }))
playlist.add(Playlist.TTS({ text: 'Hello World' }))

expect(playlist.volume).toBe(2)
expect(playlist.media).toStrictEqual([
{
type: 'audio',
url: 'https://example.com/hello.mp3',
},
{
type: 'silence',
duration: 5,
},
{
type: 'tts',
text: 'Hello World',
},
])
})
})
54 changes: 54 additions & 0 deletions packages/realtime-api/src/voice/Playlist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type {
CreateVoicePlaylistParams,
VoicePlaylist,
VoiceCallPlayParams,
VoiceCallPlayAudioParams,
VoiceCallPlayAudioMethodParams,
VoiceCallPlayTTSParams,
VoiceCallPlayTTSMethodParams,
VoiceCallPlaySilenceParams,
VoiceCallPlaySilenceMethodParams,
VoiceCallPlayRingtoneParams,
VoiceCallPlayRingtoneMethodParams,
} from '@signalwire/core'

export class Playlist implements VoicePlaylist {
private _media: VoicePlaylist['media'] = []

constructor(private params: CreateVoicePlaylistParams = {}) {}

get volume() {
return this.params?.volume
}

get media() {
return this._media
}

add(params: VoiceCallPlayParams) {
this._media.push(params)
return this
}

static Audio(
params: VoiceCallPlayAudioMethodParams
): VoiceCallPlayAudioParams {
return { type: 'audio', ...params }
}

static TTS(params: VoiceCallPlayTTSMethodParams): VoiceCallPlayTTSParams {
return { type: 'tts', ...params }
}

static Silence(
params: VoiceCallPlaySilenceMethodParams
): VoiceCallPlaySilenceParams {
return { type: 'silence', ...params }
}

static Ringtone(
params: VoiceCallPlayRingtoneMethodParams
): VoiceCallPlayRingtoneParams {
return { type: 'ringtone', ...params }
}
}
Loading