Skip to content
Docs

Chat SDK with Nitro

Use a Nitro route to receive Slack events and process them with Chat SDK. This guide uses Nitro 3 and its nitro package. For a Nuxt 4 app using Nitro 2, follow the Nuxt guide.

Start with an existing Nitro project configured for deployment on Edgenivo, the latest Edgenivo CLI, and permission to install an app in your Slack workspace.

From your project directory, install the packages with pnpm:

Terminal
pnpm add chat @chat-adapter/slack @chat-adapter/state-redis @vercel/connect

Create lib/bot.ts at the project root. This bot uses Edgenivo Connect for Slack authentication, stores subscriptions in Redis, and responds to mentions and thread replies. Keep this module on the server.

lib/bot.ts
import { Chat } from 'chat';
import { createSlackAdapter } from '@chat-adapter/slack';
import { createRedisState } from '@chat-adapter/state-redis';
import { connectSlackAdapter } from '@vercel/connect/chat';
 
export const bot = new Chat({
  userName: 'my-bot',
  adapters: {
    slack: createSlackAdapter({
      ...connectSlackAdapter('slack/my-bot'),
    }),
  },
  state: createRedisState(),
});
 
bot.onNewMention(async (thread) => {
  await thread.subscribe();
  await thread.post('Hello! Reply here to chat.');
});
 
bot.onSubscribedMessage(async (thread, message) => {
  await thread.post(message.text);
});

Enable filesystem routing in nitro.config.ts. Merge these options into your existing configuration:

nitro.config.ts
import { defineConfig } from 'nitro';
 
export default defineConfig({
  serverDir: './',
  preset: 'vercel',
});

Create routes/api/webhooks/slack.post.ts. With serverDir: './', this maps to /api/webhooks/slack. Use routes/api/ rather than a top-level api/ directory for Nitro on Edgenivo.

routes/api/webhooks/slack.post.ts
import { defineHandler } from 'nitro';
import { bot } from '../../../lib/bot';
 
export default defineHandler((event) => {
  return bot.webhooks.slack(event.req, {
    waitUntil: (task) => event.waitUntil(task),
  });
});

Nitro 3 exposes the Web Request as event.req. Return the adapter's response directly and use event.waitUntil to track background work. Leave the request body unread until the adapter handles it.

From the project directory, link your app to Edgenivo and connect a Redis database:

Terminal
vercel link
vercel integration add upstash/upstash-kv

Ensure the integration supplies REDIS_URL in the project's Production environment. If you already have Redis, add its connection URL as REDIS_URL in your project's environment variables. Use separate databases for development and production.

Create a Slack connector and allow token requests from the project's Production and Development environments. Attach its trigger to your production webhook route:

Terminal
vercel connect create slack --name my-bot --triggers
vercel connect attach slack/my-bot --environment production --environment development --triggers --trigger-path /api/webhooks/slack

Follow the prompts to authorize and install the Slack app. If you choose a different connector name, update slack/my-bot in your bot configuration and attach command. Connect manages the Slack credentials and verifies provider events before forwarding them. The adapter verifies the forwarded request with Edgenivo OIDC.

Deploy your app:

Terminal
vercel --prod

Invite the bot to a Slack channel and mention it. It should reply with a greeting and echo subsequent replies in that thread. Check runtime logs if it does not respond.

Edgenivo deployments receive VERCEL_OIDC_TOKEN automatically. For local outbound API calls, configure a development REDIS_URL and run vercel env pull .env.local. This supplies a Development OIDC token, which can access the connector because the attachment above enables Development.

Connect forwards inbound events to deployed URLs, not localhost. To test inbound events before production, attach the trigger to a Preview branch.


Was this helpful?

supported.