- Create a bot in Towns
- Set up your development environment
- Deploy to Render.com
- Configure your bot in Towns
Prerequisites
Before you begin, make sure you have:- Node.js v20+ installed (download for your OS)
- Bun installed (download for your OS)
- A GitHub account with SSH key configured (for pushing your bot code)
Create a Bot
- Visit the Developer Portal Go to app.towns.com/developer
- Create New Bot Fill in the details and click “Create Bot”.
-
Save Your Credentials
After creation, you’ll receive two critical values:
APP_PRIVATE_DATA- Your bot’s private key and encryption device (base64 encoded string)JWT_SECRET- Used to verify webhook requests from Towns servers
Store these securely - you’ll need them for deployment.
Develop Your Bot
Now let’s set up your bot development environment.Initialize Your Project
Create a new bot project using the Towns bot CLI:Install Dependencies
Add Bot Discovery Endpoint
Opensrc/index.ts and add this route after the /webhook route:
Configure Environment
Copy the.env.sample file in your project root:
Push to GitHub
Create a new repository on GitHub, follow their instructions, commit all your changes and push your bot code to it.Deploy Your Bot
We’ll deploy to Render.com, which offers a generous free tier perfect for bot hosting.- Sign up for Render Go to render.com and create an account (can use GitHub login)
-
Create New Web Service
- Click “New +” → “Web Service”
- Connect your GitHub account if prompted
- Select your bot repository
-
Configure the Service
Fill in the deployment settings:
Setting Value Name my-bot(or any name you prefer)Language NodeBuild Command bun installStart Command bun run start -
Add Environment Variables
In the “Environment” section, you can either paste your
.envfile contents or add each variable manually.Key Value APP_PRIVATE_DATAYour app private data from bot creation JWT_SECRETYour JWT secret from bot creation PORT5123 -
Deploy
Click “Create Web Service”. Render will:
- Clone your repository
- Run
bun installto build your bot - Start your bot with
bun run start
Free tier services on Render may spin down after 15 minutes of inactivity. The first request after spin-down may take 30-60 seconds. Consider upgrading to a paid plan for production bots.
Configure in Towns
Now that your bot is deployed and publicly accessible, connect it to Towns.Set Webhook URL
- Go back to app.towns.com/developer
- Click on your bot
-
Under “Webhook URL”, enter:
- Click “Save”
Configure Forwarding Settings
In the bot settings page, under “Forwarding Settings”, choose which messages your bot receives.-
All Messages - Bot receives every event in channels it’s in
- All event handlers available. See Events for more information.
- Use for: AI agents, moderation bots, analytics, or when you need tip/membership events
-
Mentions, Commands, Replies & Reactions (Default) - Bot only receives:
- Direct @mentions, replies to bot’s messages, reactions, and slash commands
- Available handlers:
onMessage(filtered),onSlashCommand,onReaction,onMessageEdit,onRedaction - NOT available:
onTip,onChannelJoin,onChannelLeave,onEventRevoke - Use for: Most interactive bots
-
No Messages - Bot receives no message events
- Use for: External-only bots (e.g., GitHub webhooks, scheduled tasks)
Install Bot to a Space
Finally, install your bot to a space to start using it:- In Towns app, go to a space you own or admin
- Go to Space Settings → Bots
- Search for your bot by username
- Click “Install”
- Grant permissions as needed
Understanding Your Bot’s Wallet Architecture
Your bot has two wallets that work together:Bot Treasury Wallet
The Bot Treasury Wallet (bot.appAddress) is a SimpleAccount (ERC-4337) smart contract that holds your bot’s funds:
- Receives funds: All tips and payments sent to your bot are stored here
- Stores assets: This is where ETH and tokens are held
- Source for payments: When your bot sends tips to users, funds come from this wallet
bot.appAddress from any wallet.
Gas Wallet
The Gas Wallet (bot.viem.account) pays for gas fees on bot transactions:
- Signs transactions: Authorizes all operations on behalf of the bot treasury
- Pays gas fees: Needs Base ETH to cover transaction costs
- Fund this wallet: Required for any blockchain transactions
When to Fund Each
Fund your Gas Wallet when:- Your bot needs to send tips to users
- Your bot performs moderation actions (ban/unban)
- Your bot interacts with smart contracts
- You see “insufficient funds for gas” errors
- Your bot needs to send tips from its treasury
- You want to receive payments and tips
- Your bot needs to hold ETH/tokens for operations
The gas wallet credentials are provided in
APP_PRIVATE_DATA during bot creation. You can extract the wallet address from this value to fund it.Testing Your Bot
Try these to verify everything works: In the channel you installed your bot to, mention your bot:Next Steps
Now that your bot is running, explore more capabilities:- Local development - Learn how to develop bots locally to fast iterate
- Learn about event handlers - Handle different event types
- Add slash commands - Create custom
/help,/poll, etc. - External interactions - Timers, webhooks, custom APIs