const tinyWave = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YQAAAAA='; const originalMessage = 'Plugin API original message'; const editedMessage = 'Plugin API edited message'; const deletedMessage = 'Plugin API deleted message'; const embedMessage = 'toju:embed:e2e.coverage:{"title":"Plugin API custom embed","body":"Rendered by plugin API"}'; const soundboardPlayedMessage = 'E2E soundboard played Airhorn to voice channel'; export async function activate(context) { const api = context.api; const currentUser = api.profile.getCurrent(); const shouldMutateChat = !currentUser?.displayName?.includes('Bob'); const pluginUserId = api.server.registerPluginUser({ displayName: 'E2E Plugin Bot', id: 'e2e-plugin-bot' }); context.subscriptions.push(api.ui.registerSettingsPage('coverage', { label: 'E2E Coverage', render: () => 'E2E settings contribution' })); context.subscriptions.push(api.ui.registerAppPage('coverage', { label: 'E2E Page', path: '/plugins/e2e/coverage', render: () => 'E2E page contribution' })); context.subscriptions.push(api.ui.registerSidePanel('coverage', { label: 'E2E Soundboard', render: () => 'E2E soundboard ready' })); context.subscriptions.push(api.ui.registerChannelSection('coverage', { label: 'E2E Soundboard', type: 'custom' })); context.subscriptions.push(api.ui.registerComposerAction('coverage', { icon: 'SFX', label: 'E2E Soundboard', run: () => openSoundboardModal(api, pluginUserId) })); context.subscriptions.push(api.ui.registerProfileAction('coverage', { label: 'E2E Profile', run: () => api.logger.info('profile action ran') })); context.subscriptions.push(api.ui.registerToolbarAction('coverage', { label: 'E2E Toolbar', run: () => api.logger.info('toolbar action ran') })); context.subscriptions.push(api.ui.registerEmbedRenderer('coverage', { embedType: 'e2e.coverage', render: (payload) => `E2E custom embed: ${payload?.title ?? 'missing title'}` })); const injectedBadge = document.createElement('div'); injectedBadge.dataset.testid = 'e2e-plugin-owned-dom'; injectedBadge.textContent = 'E2E plugin-owned DOM injected into chat'; injectedBadge.style.position = 'absolute'; injectedBadge.style.left = '1rem'; injectedBadge.style.bottom = '5.5rem'; injectedBadge.style.zIndex = '20'; injectedBadge.style.border = '1px solid hsl(var(--border))'; injectedBadge.style.borderRadius = '0.5rem'; injectedBadge.style.padding = '0.35rem 0.5rem'; injectedBadge.style.background = 'hsl(var(--card))'; injectedBadge.style.color = 'hsl(var(--foreground))'; injectedBadge.style.fontSize = '0.75rem'; context.subscriptions.push(api.ui.mountElement('chat-owned-badge', { element: injectedBadge, target: 'app-chat-messages' })); context.subscriptions.push(api.events.subscribeServer({ eventName: 'e2e:server', handler: () => {} })); context.subscriptions.push(api.events.subscribeP2p({ eventName: 'e2e:p2p', handler: () => {} })); api.storage.set('coverage', { ok: true }); api.storage.get('coverage'); await api.clientData.write('coverage', { ok: true }); await api.clientData.read('coverage'); await api.serverData.write('coverage', { ok: true }); await api.serverData.read('coverage'); api.profile.update({ description: 'Updated by E2E plugin', displayName: `${currentUser?.displayName || 'E2E Plugin User'} Plugin Renamed` }); api.profile.updateAvatar({ avatarHash: 'e2e-plugin-avatar', avatarMime: 'image/svg+xml', avatarUrl: '/plugins/e2e-all-api/icon.svg' }); api.users.getCurrent(); api.users.list(); api.users.readMembers(); api.users.setRole(pluginUserId, 'member'); api.users.kick(pluginUserId); api.users.ban(pluginUserId, 'E2E coverage'); api.roles.list(); api.roles.setAssignments([]); api.channels.list(); api.channels.addAudioChannel({ id: 'e2e-audio', name: 'E2E Audio', position: 90 }); api.channels.addVideoChannel({ id: 'e2e-video', name: 'E2E Video', position: 91 }); api.channels.select('general'); api.channels.rename('e2e-audio', 'E2E Audio Renamed'); api.server.getCurrent(); api.server.updatePermissions({ allowVoice: true }); api.server.updateSettings({ name: api.server.getCurrent()?.name, topic: 'Updated by E2E plugin' }); api.messages.readCurrent(); if (shouldMutateChat) { const sentMessage = api.messages.send(originalMessage); api.messages.edit(sentMessage.id, editedMessage); const removableMessage = api.messages.send(deletedMessage); api.messages.delete(removableMessage.id); api.messages.send(embedMessage); } api.messages.sendAsPluginUser({ content: 'Plugin bot message from all-api fixture', pluginUserId }); api.messages.moderateDelete('missing-message-id'); api.messages.sync(api.messages.readCurrent()); context.subscriptions.push(api.messageBus.subscribe({ handler: () => {}, latestMessageLimit: 5, replayLatest: true, topic: 'e2e:latest' })); api.messageBus.publish({ includeLatestMessages: true, includeSelf: true, latestMessageLimit: 5, payload: { ok: true }, topic: 'e2e:latest' }); api.messageBus.sendLatestMessages({ limit: 5, topic: 'e2e:latest' }); api.p2p.connectedPeers(); api.p2p.broadcastData('e2e:p2p', { ok: true }); api.p2p.sendData('missing-peer', 'e2e:p2p', { ok: true }); api.events.publishServer('e2e:server', { ok: true }); api.events.publishP2p('e2e:p2p', { ok: true }); api.media.setOutputVolume(0.8); api.media.setInputVolume(0.8); await api.media.playAudioClip({ url: tinyWave, volume: 0 }).catch((error) => api.logger.warn('audio clip rejected', String(error))); await api.media.addCustomVideoStream({ label: 'e2e-video', stream: new MediaStream() }); const audioContext = new AudioContext(); const destination = audioContext.createMediaStreamDestination(); await api.media.addCustomAudioStream({ label: 'e2e-audio', stream: destination.stream }).catch((error) => api.logger.warn('audio stream rejected', String(error))); await audioContext.close(); api.storage.remove('coverage'); await api.clientData.remove('coverage'); await api.serverData.remove('coverage'); api.logger.info('all-api plugin completed'); } export function ready(context) { context.api.logger.info('all-api plugin ready'); } export function deactivate(context) { context.api.logger.info('all-api plugin deactivated'); } function openSoundboardModal(api, pluginUserId) { document.querySelector('[data-testid="e2e-soundboard-modal"]')?.remove(); const overlay = document.createElement('div'); overlay.dataset.testid = 'e2e-soundboard-modal'; overlay.setAttribute('role', 'dialog'); overlay.setAttribute('aria-modal', 'true'); overlay.setAttribute('aria-label', 'E2E Soundboard'); overlay.style.position = 'fixed'; overlay.style.inset = '0'; overlay.style.zIndex = '9999'; overlay.style.display = 'grid'; overlay.style.placeItems = 'center'; overlay.style.background = 'rgb(0 0 0 / 0.45)'; const panel = document.createElement('section'); panel.style.width = 'min(24rem, calc(100vw - 2rem))'; panel.style.border = '1px solid hsl(var(--border))'; panel.style.borderRadius = '0.5rem'; panel.style.padding = '1rem'; panel.style.color = 'hsl(var(--foreground))'; panel.style.background = 'hsl(var(--card))'; panel.style.boxShadow = '0 1.25rem 3rem rgb(0 0 0 / 0.25)'; const title = document.createElement('h2'); title.textContent = 'E2E Soundboard'; title.style.margin = '0 0 0.75rem'; title.style.fontSize = '1rem'; const status = document.createElement('p'); status.dataset.testid = 'e2e-soundboard-status'; status.textContent = 'Ready to play to voice channel'; status.style.margin = '0 0 1rem'; status.style.color = 'hsl(var(--muted-foreground))'; status.style.fontSize = '0.875rem'; const actions = document.createElement('div'); actions.style.display = 'flex'; actions.style.gap = '0.5rem'; actions.style.justifyContent = 'flex-end'; const closeButton = document.createElement('button'); closeButton.type = 'button'; closeButton.textContent = 'Close'; closeButton.style.border = '1px solid hsl(var(--border))'; closeButton.style.borderRadius = '0.375rem'; closeButton.style.padding = '0.5rem 0.75rem'; closeButton.style.background = 'transparent'; closeButton.style.color = 'hsl(var(--foreground))'; closeButton.addEventListener('click', () => overlay.remove()); const playButton = document.createElement('button'); playButton.type = 'button'; playButton.textContent = 'Play airhorn to voice'; playButton.style.border = '0'; playButton.style.borderRadius = '0.375rem'; playButton.style.padding = '0.5rem 0.75rem'; playButton.style.background = 'hsl(var(--primary))'; playButton.style.color = 'hsl(var(--primary-foreground))'; playButton.addEventListener('click', async () => { playButton.disabled = true; status.textContent = 'Playing Airhorn to voice channel'; try { await playSoundboardClipToVoice(api); api.p2p.broadcastData('e2e:p2p', { sound: 'airhorn', source: 'soundboard' }); api.events.publishP2p('e2e:p2p', { sound: 'airhorn', source: 'soundboard' }); api.messages.sendAsPluginUser({ content: soundboardPlayedMessage, pluginUserId }); api.logger.info('soundboard played to voice channel'); status.textContent = soundboardPlayedMessage; } catch (error) { status.textContent = error instanceof Error ? error.message : 'Soundboard playback failed'; api.logger.warn('soundboard playback failed', String(error)); } finally { playButton.disabled = false; } }); actions.append(closeButton, playButton); panel.append(title, status, actions); overlay.append(panel); api.ui.mountElement('soundboard-modal', { element: overlay, target: 'body' }); } async function playSoundboardClipToVoice(api) { const audioContext = new AudioContext(); const oscillator = audioContext.createOscillator(); const gain = audioContext.createGain(); const destination = audioContext.createMediaStreamDestination(); oscillator.type = 'square'; oscillator.frequency.value = 330; gain.gain.value = 0.08; oscillator.connect(gain); gain.connect(destination); oscillator.start(); await api.media.addCustomAudioStream({ label: 'e2e-soundboard-airhorn', stream: destination.stream }); await api.media.playAudioClip({ url: tinyWave, volume: 0 }).catch((error) => api.logger.warn('soundboard preview rejected', String(error))); await new Promise((resolve) => setTimeout(resolve, 150)); oscillator.stop(); await audioContext.close(); }