--- sidebar_position: 1 --- # Context and Logging Context and logging are available to every plugin. They do not require privileged capabilities. ## context.getCurrent() Reads the current interaction context. ```js export function activate(context) { const current = context.api.context.getCurrent(); context.api.logger.info('Current context', { serverName: current.server?.name ?? 'No server open', textChannel: current.textChannel?.name ?? 'No text channel selected', voiceChannel: current.voiceChannel?.name ?? 'Not connected to voice', user: current.user?.displayName ?? 'No user' }); } ``` Example context shape: ```json { "source": "manual", "server": { "id": "room-7ebdde75", "name": "Friday Game Night" }, "textChannel": { "id": "general", "name": "general", "type": "text" }, "voiceChannel": { "id": "lobby", "name": "Lobby", "type": "audio" }, "user": { "id": "user-alice-01", "displayName": "Alice" } } ``` ## Action Context Composer, toolbar, and profile actions receive context directly. ```js export function activate(context) { context.subscriptions.push(context.api.ui.registerToolbarAction('where-am-i', { label: 'Where am I?', run: (actionContext) => { context.api.logger.info('Toolbar action context', { source: actionContext.source, serverId: actionContext.server?.id, textChannelId: actionContext.textChannel?.id, voiceChannelId: actionContext.voiceChannel?.id }); } })); } ``` Capability required: `ui.pages` for the toolbar action. The context object itself needs no extra capability. ## Logger Methods ```js export function activate(context) { const { logger } = context.api; logger.debug('Preparing plugin', { pluginId: context.pluginId }); logger.info('Plugin activated', { version: context.manifest.version }); logger.warn('Optional service unavailable', { service: 'weather.example.com' }); logger.error('Failed to parse saved preference', { key: 'soundboard:favorites' }); } ``` Logs are visible in the Plugin Manager. Avoid logging passwords, bearer tokens, or private message contents.