Skip to content

Commit edc797f

Browse files
authored
Merge pull request #136 from berkmancenter/jh/no-zoom-mod-report-hybrid
feat: do not send moderator report to Zoom chat in hybrid events
2 parents 7827702 + 91191d2 commit edc797f

3 files changed

Lines changed: 80 additions & 3 deletions

File tree

src/conversations/eventAssistant.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ const eventAssistant: ConversationType = {
235235
{ name: 'image-gen' }
236236
],
237237
adapters: {
238+
// Fully remote: Zoom only — moderator DMs sent via Zoom
238239
zoom: {
239240
type: 'zoom',
240241
config: {
@@ -265,6 +266,33 @@ const eventAssistant: ConversationType = {
265266
}
266267
]
267268
},
269+
// Hybrid: Zoom + NextSpace — moderator DMs handled by NextSpace, not Zoom
270+
'nextspace,zoom': {
271+
type: 'zoom',
272+
config: {
273+
meetingUrl: '{{{properties.zoomMeetingUrl}}}',
274+
botName: '{{properties.botName}}'
275+
},
276+
dmChannels: [
277+
{
278+
direct: true,
279+
agent: 'eventAssistant',
280+
direction: Direction.BOTH
281+
}
282+
],
283+
chatChannels: [
284+
{
285+
name: 'chat',
286+
direction: Direction.BOTH
287+
}
288+
],
289+
audioChannels: [
290+
{
291+
name: 'transcript',
292+
direction: Direction.INCOMING
293+
}
294+
]
295+
},
268296
default: {
269297
// Zoom transcription only - assume DMs are coming through web or websocket APIs
270298
type: 'zoom',

src/conversations/resolver.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,14 @@ export default function resolveConversationType(
232232
for (const { name, config, enabled } of features) if (enabled) workingProperties[name] = config ?? true
233233

234234
const adapterDefs = conversationType.adapters || {}
235-
const matched = (platforms || []).map((p) => adapterDefs[p]).filter(Boolean)
235+
const sortedKey = (platforms || []).slice().sort().join(',')
236+
const exactMatch = adapterDefs[sortedKey]
237+
const perPlatform = (platforms || []).map((p) => adapterDefs[p]).filter(Boolean)
236238
let adapters: unknown[] = []
237-
if (matched.length > 0) {
238-
adapters = matched.map((a) => resolvePropertyReferences(a, workingProperties))
239+
if (exactMatch) {
240+
adapters = [resolvePropertyReferences(exactMatch, workingProperties)]
241+
} else if (perPlatform.length > 0) {
242+
adapters = perPlatform.map((a) => resolvePropertyReferences(a, workingProperties))
239243
} else if (adapterDefs.default) {
240244
adapters = [resolvePropertyReferences(adapterDefs.default, workingProperties)]
241245
}

tests/conversations/resolver.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,51 @@ describe('resolveConversationType', () => {
296296
const result = resolveConversationType({ platforms: ['web'] }, type)
297297
expect(result.adapters).toHaveLength(0)
298298
})
299+
300+
test('matches composite platform key over individual keys', () => {
301+
const type: ConversationType = {
302+
...baseType,
303+
properties: [],
304+
adapters: {
305+
zoom: { type: 'zoom', config: { variant: 'zoom-only' } },
306+
'nextspace,zoom': { type: 'zoom', config: { variant: 'hybrid' } },
307+
default: { type: 'web' }
308+
}
309+
}
310+
const result = resolveConversationType({ platforms: ['zoom', 'nextspace'] }, type)
311+
expect(result.adapters).toHaveLength(1)
312+
expect(result.adapters[0]).toMatchObject({ config: { variant: 'hybrid' } })
313+
})
314+
315+
test('composite key matches regardless of platform order', () => {
316+
const type: ConversationType = {
317+
...baseType,
318+
properties: [],
319+
adapters: {
320+
'nextspace,zoom': { type: 'zoom', config: { variant: 'hybrid' } },
321+
default: { type: 'web' }
322+
}
323+
}
324+
const result = resolveConversationType({ platforms: ['nextspace', 'zoom'] }, type)
325+
expect(result.adapters).toHaveLength(1)
326+
expect(result.adapters[0]).toMatchObject({ config: { variant: 'hybrid' } })
327+
})
328+
329+
test('falls back to per-platform adapters when no composite key matches', () => {
330+
const type: ConversationType = {
331+
...baseType,
332+
properties: [],
333+
adapters: {
334+
zoom: { type: 'zoom' },
335+
'nextspace,zoom': { type: 'zoom', config: { variant: 'hybrid' } }
336+
}
337+
}
338+
// Only zoom platform — matches single 'zoom' key, not composite
339+
const result = resolveConversationType({ platforms: ['zoom'] }, type)
340+
expect(result.adapters).toHaveLength(1)
341+
expect(result.adapters[0]).toMatchObject({ type: 'zoom' })
342+
expect((result.adapters[0] as { config?: { variant?: string } }).config?.variant).toBeUndefined()
343+
})
299344
})
300345

301346
describe('passthrough fields', () => {

0 commit comments

Comments
 (0)