Module 4

Admin Permissions & Security

Learn how to identify admins, delete messages, and implement basic content moderation. Build the essential moderation tools your bot needs to keep channels safe and organized.

3 steps
Intermediate

Learning Objectives

By the end of this module, you will be able to:

Check if users have admin permissions using slash commands
Delete messages programmatically for moderation
Filter and moderate content with automated keyword detection
1

Admin Permissions

Learn how to check if users have admin permissions in your space using the built-in Towns Protocol method.

Checking Admin Permissions

Use the handler.hasAdminPermission() method to check if a user has admin rights in a space.

Admin Permission Check
bot.onSlashCommand('admin', async (handler, { channelId, spaceId, userId }) => {
  try {
    // Check if user has admin permissions
    const isAdmin = await handler.hasAdminPermission(userId, spaceId)
    
    if (!isAdmin) {
      await handler.sendMessage(
        channelId,
        `❌ <@${userId}>, you need admin permissions to use this command.`
      )
      return
    }
    
    // User is admin - show admin panel
  await handler.sendMessage(channelId, `
🛡️ **Admin Panel**

You have admin permissions! Here's what you can do:

**Moderation Commands:**
• `/delete [messageId]` - Delete a message
• `/clear [count]` - Clear multiple messages
• `/warn @user [reason]` - Warn a user

**Channel Management:**
• `/lock` - Lock the channel
• `/unlock` - Unlock the channel

*All admin actions are logged.*
    `)
    
  } catch (error) {
    console.error('Error checking admin permissions:', error)
    await handler.sendMessage(channelId, '❌ Error checking permissions.')
  }
})

How It Works

The hasAdminPermission() method checks if a user has admin rights in the Towns Protocol space. This is the built-in way to verify permissions - no database needed!

2

Deleting Messages

Learn how to programmatically delete messages for moderation purposes.

Delete Message Command

Use handler.deleteMessage() to remove messages from channels. Always check admin permissions first.

Message Deletion
bot.onSlashCommand('delete', async (handler, { channelId, spaceId, userId, args }) => {
  try {
    // IMPORTANT: Each command is stateless - no message history access
    // Message deletion requires the Redaction API

    // Check admin permissions
    const isAdmin = await handler.hasAdminPermission(userId, spaceId)

    if (!isAdmin) {
      await handler.sendMessage(
        channelId,
        `❌ Only admins can delete messages.`
      )
      return
    }

    // Get message ID from arguments
    const messageId = args?.[0]

    if (!messageId) {
      await handler.sendMessage(channelId, `❌ Usage: `/delete [messageId]``)
      return
    }

    // Delete the message using Redaction API
    // Note: The bot needs "Delete Messages" permission in Developer Portal
    await handler.redactMessage(messageId, 'Admin deletion')

    // Confirm deletion
    await handler.sendMessage(
      channelId,
      `✅ Message ${messageId} deleted by <@${userId}>`
    )

    // Log the action
    console.log(`Admin ${userId} deleted message ${messageId} in ${channelId}`)

  } catch (error) {
    console.error('Error deleting message:', error)
    await handler.sendMessage(channelId, '❌ Failed to delete message. Check bot permissions.')
  }
})

Best Practices

  • • Always verify admin permissions before deleting
  • • Log all deletion actions for audit trails
  • • Provide clear feedback to the admin
  • • Handle errors gracefully

🎯 Exercise: Build /purge Command

Complete the purge command with admin checks and message deletion.

3

Content Moderation

Automatically filter and moderate content using keyword detection.

Keyword Filtering

Detect banned words or phrases and automatically take action to keep your channels safe.

Content Filter
// Define banned words/phrases
const BANNED_WORDS = ['spam', 'scam', 'inappropriate-word']

bot.onMessage(async (handler, event) => {
  const { message, userId, channelId, eventId, spaceId } = event

  // IMPORTANT: Each message event is stateless
  // No access to previous messages or conversation context

  // Skip bot messages
  if (userId === bot.botId) return

  // Check for banned content
  const lowerMessage = message.toLowerCase()
  const containsBannedWord = BANNED_WORDS.some(word =>
    lowerMessage.includes(word)
  )

  if (containsBannedWord) {
    try {
      // Delete the message using redaction API
      // Bot needs "Delete Messages" permission
      await handler.redactMessage(eventId, 'Contains banned content')

      // Warn the user
      await handler.sendMessage(
        channelId,
        `⚠️ <@${userId}>, your message was removed for violating community guidelines.`
      )

      // Log the moderation action
      console.log(`Moderated message from ${userId}: "${message}"`)

    } catch (error) {
      console.error('Error moderating content:', error)
      // Silent fail - don't disrupt chat if moderation fails
    }
  }
})

Do This

  • • Keep banned word lists updated
  • • Log all moderation actions
  • • Provide clear feedback to users
  • • Use case-insensitive matching

Avoid This

  • • Over-aggressive filtering
  • • Deleting without explanation
  • • Ignoring false positives
  • • Not logging moderation actions

Module 4 Complete!

You've learned the essentials of admin permissions and content moderation! You can now check admin permissions, delete messages, and filter content.