Skip to content

Commit

Permalink
Expose RoomSession setMeta and setMemberMeta methods (#452)
Browse files Browse the repository at this point in the history
* initial changes for setMeta and setMemberMeta

* add meta to RoomSession and Member

* update setMeta params

* docs

* changeset

* fix setMeta rpc params

Co-authored-by: Daniele Di Sarli <danieleds0@gmail.com>
  • Loading branch information
edolix and danieleds authored Mar 9, 2022
1 parent 4692b05 commit 563a31e
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 5 deletions.
7 changes: 7 additions & 0 deletions .changeset/perfect-snails-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@signalwire/core': patch
'@signalwire/js': patch
'@signalwire/realtime-api': patch
---

Expose `setMeta` and `setMemberMeta` methods on the RoomSession.
24 changes: 24 additions & 0 deletions packages/core/src/rooms/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ export const play: RoomMethodDescriptor<any, PlayParams> = {
},
}

export interface SetMetaParams extends Record<string, unknown> {}
export const setMeta = createRoomMethod<BaseRPCResult, void, SetMetaParams>(
'video.set_meta',
{
transformResolve: baseCodeTransform,
transformParams: (params) => {
const { room_session_id, ...meta } = params
return { room_session_id, meta }
},
}
)

export type GetLayouts = ReturnType<typeof getLayouts.value>
export type GetMembers = ReturnType<typeof getMembers.value>
export type HideVideoMuted = ReturnType<typeof hideVideoMuted.value>
Expand All @@ -257,6 +269,7 @@ export type StartRecording = ReturnType<typeof startRecording.value>

export type GetPlaybacks = ReturnType<typeof getPlaybacks.value>
export type Play = ReturnType<typeof play.value>
export type SetMeta = ReturnType<typeof setMeta.value>
// End Room Methods

/**
Expand Down Expand Up @@ -367,6 +380,16 @@ export const removeMember: RoomMethodDescriptor<
},
}

export interface SetMemberMetaParams extends MemberCommandParams {
meta: Record<string, unknown>
}
export const setMemberMeta = createRoomMemberMethod<BaseRPCResult, void>(
'video.member.set_meta',
{
transformResolve: baseCodeTransform,
}
)

export type AudioMuteMember = ReturnType<typeof audioMuteMember.value>
export type AudioUnmuteMember = ReturnType<typeof audioUnmuteMember.value>
export type VideoMuteMember = ReturnType<typeof videoMuteMember.value>
Expand All @@ -385,4 +408,5 @@ export type SetInputSensitivityMember = ReturnType<
>
export type SetMemberPosition = ReturnType<typeof setMemberPosition.value>
export type RemoveMember = ReturnType<typeof removeMember.value>
export type SetMemberMeta = ReturnType<typeof setMemberMeta.value>
// End Room Member Methods
2 changes: 2 additions & 0 deletions packages/core/src/types/videoMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const INTERNAL_MEMBER_UPDATABLE_PROPS = {
input_volume: 1,
output_volume: 1,
input_sensitivity: 1,
meta: {},
}
export type InternalVideoMemberUpdatableProps =
typeof INTERNAL_MEMBER_UPDATABLE_PROPS
Expand Down Expand Up @@ -63,6 +64,7 @@ type VideoMemberUpdatableProps = AssertSameType<
* The default value is 30 and the scale goes from 0 (lowest sensitivity,
* essentially muted) to 100 (highest sensitivity). */
inputSensitivity: number
meta: Record<string, unknown>
}
>

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types/videoRoomSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface VideoRoomSessionContract {
hideVideoMuted: boolean
/** URL to the room preview. */
previewUrl?: string
meta: Record<string, unknown>

audioMute(params?: MemberCommandParams): Rooms.AudioMuteMember
audioUnmute(params?: MemberCommandParams): Rooms.AudioUnmuteMember
Expand Down Expand Up @@ -97,6 +98,9 @@ export interface VideoRoomSessionContract {
startRecording(): Promise<Rooms.RoomSessionRecording>
getPlaybacks(): Rooms.GetPlaybacks
play(params: Rooms.PlayParams): Promise<Rooms.RoomSessionPlayback>

setMeta(params: Rooms.SetMetaParams): Rooms.SetMeta
setMemberMeta(params: Rooms.SetMemberMetaParams): Rooms.SetMemberMeta
}

/**
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/utils/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ export type RoomMethod =
| 'video.member.set_input_sensitivity'
| 'video.member.set_position'
| 'video.member.remove'
| 'video.member.set_meta'
| 'video.set_meta'
| 'video.set_layout'
| 'video.set_position'
| 'video.recording.list'
Expand Down
80 changes: 80 additions & 0 deletions packages/js/src/BaseRoomSession.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ describe('Room Object', () => {
expect(room.startRecording).toBeDefined()
expect(room.getPlaybacks).toBeDefined()
expect(room.play).toBeDefined()
expect(room.setMeta).toBeDefined()
expect(room.setMemberMeta).toBeDefined()
})

describe('getRecordings', () => {
Expand Down Expand Up @@ -399,4 +401,82 @@ describe('Room Object', () => {
)
})
})

describe('meta methods', () => {
it('should allow to set the meta field on the RoomSession', async () => {
const { store, session, emitter } = configureFullStack()

session.execute = jest.fn().mockResolvedValue({
code: '200',
message: 'OK',
})

room = createBaseRoomSessionObject({
store,
// @ts-expect-error
emitter,
})
// mock a room.subscribed event
// @ts-expect-error
room.onRoomSubscribed({
nodeId: 'node-id',
roomId: '6e83849b-5cc2-4fc6-80ed-448113c8a426',
roomSessionId: '8e03ac25-8622-411a-95fc-f897b34ac9e7',
memberId: 'member-id',
})

const result = await room.setMeta({ foo: 'bar' })
expect(result).toBeUndefined()

expect(session.execute).toHaveBeenLastCalledWith({
jsonrpc: '2.0',
id: expect.any(String),
method: 'video.set_meta',
params: {
room_session_id: '8e03ac25-8622-411a-95fc-f897b34ac9e7',
meta: { foo: 'bar' },
},
})
})

it('should allow to set the meta field on the Member', async () => {
const { store, session, emitter } = configureFullStack()

session.execute = jest.fn().mockResolvedValue({
code: '200',
message: 'OK',
})

room = createBaseRoomSessionObject({
store,
// @ts-expect-error
emitter,
})
// mock a room.subscribed event
// @ts-expect-error
room.onRoomSubscribed({
nodeId: 'node-id',
roomId: '6e83849b-5cc2-4fc6-80ed-448113c8a426',
roomSessionId: '8e03ac25-8622-411a-95fc-f897b34ac9e7',
memberId: 'member-id',
})

const result = await room.setMemberMeta({
memberId: 'uuid',
meta: { displayName: 'jest' },
})
expect(result).toBeUndefined()

expect(session.execute).toHaveBeenLastCalledWith({
jsonrpc: '2.0',
id: expect.any(String),
method: 'video.member.set_meta',
params: {
room_session_id: '8e03ac25-8622-411a-95fc-f897b34ac9e7',
member_id: 'uuid',
meta: { displayName: 'jest' },
},
})
})
})
})
2 changes: 2 additions & 0 deletions packages/js/src/BaseRoomSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ export const RoomSessionAPI = extendComponent<
getPlaybacks: Rooms.getPlaybacks,
play: Rooms.play,
setHideVideoMuted: Rooms.setHideVideoMuted,
setMeta: Rooms.setMeta,
setMemberMeta: Rooms.setMemberMeta,
})

type RoomSessionObjectEventsHandlerMapping = RoomSessionObjectEvents &
Expand Down
69 changes: 69 additions & 0 deletions packages/js/src/RoomSession.docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,75 @@ interface RoomControlMethodsInterfaceDocs {
volume?: number
positions?: VideoPositions
}): Promise<Rooms.RoomSessionPlayback>

/**
* Assigns custom metadata to the RoomSession. You can use this to store
* metadata whose meaning is entirely defined by your application.
*
* Note that calling this method overwrites any metadata that had been
* previously set on this RoomSession.
*
* @param meta The medatada object to assign to the RoomSession.
*
* @permissions
* - `room.set_meta`
*
* You need to specify the permissions when [creating the Video Room
* Token](https://developer.signalwire.com/apis/reference/create_room_token)
* on the server side.
*
* @example
* ```js
* await roomSession.setMeta({ foo: 'bar' })
* ```
*/
setMeta(meta: Record<string, unknown>): Rooms.SetMeta

/**
* Assigns custom metadata to the specified RoomSession member. You can use
* this to store metadata whose meaning is entirely defined by your
* application.
*
* Note that calling this method overwrites any metadata that had been
* previously set on the specified member.
*
* @param params.memberId Id of the member to affect. If omitted, affects the
* default device in the local client.
* @param params.meta The medatada object to assign to the member.
*
* @permissions
* - `room.self.set_meta`: to set the metadata for the local member
* - `room.member.set_meta`: to set the metadata for a remote member
*
* You need to specify the permissions when [creating the Video Room
* Token](https://developer.signalwire.com/apis/reference/create_room_token)
* on the server side.
*
* @example
* Setting metadata for the current member:
* ```js
* await roomSession.setMemberMeta({
* meta: {
* email: 'joe@example.com'
* }
* })
* ```
*
* @example
* Setting metadata for another member:
* ```js
* await roomSession.setMemberMeta({
* memberId: 'de550c0c-3fac-4efd-b06f-b5b8614b8966' // you can get this from getMembers()
* meta: {
* email: 'joe@example.com'
* }
* })
* ```
*/
setMemberMeta(params: {
memberId?: string
meta: Record<string, unknown>
}): Rooms.SetMemberMeta
}

interface RoomLayoutMethodsInterface {
Expand Down
8 changes: 3 additions & 5 deletions packages/js/src/RoomSession.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
UserOptions,
AssertSameType,
getLogger,
} from '@signalwire/core'
import { UserOptions, AssertSameType, getLogger } from '@signalwire/core'
import { createClient } from './createClient'
import type { MakeRoomOptions } from './Client'
import { BaseRoomSession } from './BaseRoomSession'
Expand Down Expand Up @@ -43,6 +39,8 @@ export const UNSAFE_PROP_ACCESS = [
'videoUnmute',
'setMicrophoneVolume',
'setSpeakerVolume',
'setMeta',
'setMemberMeta',
]

export interface RoomSessionOptions extends UserOptions, MakeRoomOptions {}
Expand Down
45 changes: 45 additions & 0 deletions packages/realtime-api/src/video/RoomSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,49 @@ interface RoomSessionDocs extends RoomSessionMain {
positions?: VideoPositions
}): Promise<Rooms.RoomSessionPlayback>

/**
* Assigns custom metadata to the RoomSession. You can use this to store
* metadata whose meaning is entirely defined by your application.
*
* Note that calling this method overwrites any metadata that had been
* previously set on this RoomSession.
*
* @param meta The medatada object to assign to the RoomSession.
*
* @example
* ```js
* await roomSession.setMeta({ foo: 'bar' })
* ```
*/
setMeta(meta: Record<string, unknown>): Rooms.SetMeta

/**
* Assigns custom metadata to the specified RoomSession member. You can use
* this to store metadata whose meaning is entirely defined by your
* application.
*
* Note that calling this method overwrites any metadata that had been
* previously set on the specified member.
*
* @param params.memberId Id of the member to affect.
* @param params.meta The medatada object to assign to the member.
*
* @example
* Setting metadata for a member:
* ```js
* await roomSession.setMemberMeta({
* memberId: 'de550c0c-3fac-4efd-b06f-b5b8614b8966' // you can get this from getMembers()
* meta: {
* email: 'joe@example.com'
* }
* })
* ```
*/
setMemberMeta(params: {
memberId: string
meta: Record<string, unknown>
}): Rooms.SetMemberMeta

/**
* Listens for the events for which you have provided event handlers and
* returns the {@link RoomSessionFullState} that contains the full state of
Expand Down Expand Up @@ -771,6 +814,8 @@ export const RoomSessionAPI = extendComponent<
startRecording: Rooms.startRecording,
getPlaybacks: Rooms.getPlaybacks,
play: Rooms.play,
setMeta: Rooms.setMeta,
setMemberMeta: Rooms.setMemberMeta,
})

export const createRoomSessionObject = (
Expand Down

0 comments on commit 563a31e

Please sign in to comment.