Storytime Slack Bot
An interactive AI-powered Slack bot that creates collaborative children's stories with your team. The /storytime slash command opens a configuration modal with defaults pre-selected. Submit it to start a story.
Team members can then contribute to the story in a thread, with the AI helping to guide the narrative to completion and generating a storyboard image at the end. Use /storytime --video to generate an animated video instead.
Getting Started
Prerequisites
- Node.js 22.12+
- pnpm (recommended) or npm
- A Slack workspace where you can install apps
- Vercel account for deployment
1. Clone the Repository
git clone https://github.com/vercel/storytime-slackbot.git
cd storytime-slackbot
pnpm install2. Set Up Slack App
-
Go to api.slack.com/apps and create a new app
-
Choose "From scratch" and select your workspace
-
In OAuth & Permissions, add these Bot Token Scopes:
chat:writefiles:writereactions:writechannels:historygroups:historyim:historympim:history
-
In Event Subscriptions:
- Enable events
- Set Request URL to:
https://your-domain.vercel.app/api/slack/webhook - Subscribe to
message.channelsworkspace event
-
In Slash Commands, create a new command:
- Command:
/storytime - Request URL:
https://your-domain.vercel.app/api/slack/command - Description: "Start a collaborative story"
- Command:
-
In Interactivity & Shortcuts, enable interactivity and set the Request URL to
https://your-domain.vercel.app/api/slack/interactions. Under Select Menus, set the Options Load URL to the same URL. It populates the model menus in the configuration modal -
Install the app to your workspace and copy the Bot User OAuth Token
-
Copy the Signing Secret from Basic Information > App Credentials for the environment configuration below
3. Set Up AI Gateway API Key
- Navigate to the Vercel Dashboard and go to the AI Gateway tab
- Click "API keys" in the left sidebar
- Click "Create key" to generate a new API key
- Save the API key for the next step
For more details, see the AI Gateway Authentication documentation.
4. Environment Variables
Create a .env.local file:
SLACK_BOT_TOKEN=xoxb-your-bot-token-here
SLACK_SIGNING_SECRET=your_slack_signing_secret
AI_GATEWAY_API_KEY=your_ai_gateway_api_keyIf the selected image or video model fails, the bot posts a notice in the story thread and tries up to two fallback models, defined in lib/fallback-models.ts. If every model fails, the bot posts the error in the story thread with a link to the workflow run in the Vercel dashboard. The link uses the team slug and project name from the deployment's OIDC token. If OIDC is disabled, set VERCEL_TEAM_SLUG and VERCEL_PROJECT_NAME instead. Without either, the error shows the run ID without a link.
SLACK_SIGNING_SECRET is required to verify slash commands, modal submissions, and Events API requests. Set it before configuring or verifying the Slack request URLs. Existing installations must also add this variable when upgrading.
AI Gateway request transcripts are disabled for Slack sessions. The local script can opt in with pnpm tsx local.ts --transcripts, after you enable transcripts in your team's AI Gateway settings. Transcripts record prompts, files, and outputs for the session's story and image or video requests, including participants' contributions. This applies to new requests only and does not enable audio transcription.
5. Development
pnpm devThe app will be available at http://localhost:3000.
For local development with Slack webhooks, use a tool like ngrok to expose your local server:
ngrok http 3000Then update your Slack app's webhook URLs to use the ngrok URL.
Deployment
Update Slack App URLs
After deployment, update your Slack app configuration:
- Event Subscriptions Request URL:
https://your-app.vercel.app/api/slack/webhook - Slash Command Request URL:
https://your-app.vercel.app/api/slack/command - Interactivity & Shortcuts Request URL:
https://your-app.vercel.app/api/slack/interactions - Interactivity & Shortcuts Select Menus Options Load URL:
https://your-app.vercel.app/api/slack/interactions
How to Use
- First, invite the bot to your channel: Type
@Storytime Bot(or whatever you named your app) in the channel and Slack will give you the option to invite it - In any Slack channel where the bot is present, type
/storytime - Review the configuration modal. It includes output mode, themes, visual style, models, panel count, video duration, and thinking emoji, with current defaults filled in. Each model menu lists matching AI Gateway models. Type to search, or pick the first option to use exactly what you typed
- Click Start Story to generate the introduction in the original channel. Canceling the modal does not start a story
- Reply in the thread to add your part of the story
- The bot will respond with encouragement and continue the narrative
- After 2-3 iterations, the bot will conclude the story
- The selected storyboard image or video will be generated and shared
Note: The bot must be invited to a channel before the /storytime slash command will work in that channel.
Command Options
The /storytime command supports optional flags to pre-fill the configuration modal. Flags do not skip the modal; click Start Story to confirm. Selecting Image or Video shows only that mode's settings. Switching modes preserves entered values, and only the selected mode's settings are validated and used.
| Flag | Alias | Description |
|---|---|---|
--theme | -t | Story theme (can be specified multiple times). Defaults to 2 random themes if fewer than 2 are provided. |
--model | -m | Text generation model. Default: anthropic/claude-haiku-4.5 |
--image-model | -i | Image generation model. Default: google/gemini-3-pro-image |
--style | -s | Visual style for the generated image or video (e.g., "watercolor", "pencil sketch", "claymation"). |
--video | Generate a video instead of the final storyboard image. | |
--video-model | Video generation model used with --video. Default: google/veo-3.1-generate-001 | |
--video-duration | Video duration in seconds, used with --video. Must be positive; supported values depend on the model. Omit to use the model's default. | |
--panels | -p | Number of panels in the final storyboard image (integer, 2–12). Default: 4–5 panels. |
--thinking-emoji | -e | Emoji shown while processing. Default: thinking_face 🤔 |
The --model and --image-model flags accept AI Gateway model specifiers (e.g., anthropic/claude-sonnet-4, openai/gpt-4.1-mini, google/gemini-2.5-flash).
The --video-model flag also accepts an AI Gateway model specifier. The model must support asynchronous video generation with webhooks. Video generation uses experimental_generateVideo from @ai-sdk/workflow/video: the workflow suspends while the video renders, then uploads the result to the Slack thread and broadcasts it to the channel. It uses the same AI_GATEWAY_API_KEY; no additional provider key is required.
Before rendering, the selected text model (--model) adapts the completed story into a timed script: setup, main action, resolution, then a final hold. For an 8-second clip, the slots are 0-2s, 2-5s, 5-7s, and 7-8s. Explicit durations use seconds; when duration is omitted, timing uses percentages of the model's default clip length. The script prioritizes the main events and ending over secondary details, aiming for a complete short adaptation rather than a verbatim retelling. Timing is guidance for the video model, not a guarantee. This adds one text-generation request, but still generates a single video.
The --style option applies to both image and video output. The --image-model and --panels options only affect image output. Without --video, the bot continues to generate a storyboard image.
The provider must be able to reach the generated /.well-known/workflow/v1/webhook/... URL. The installed Workflow SDK uses the deployment-specific VERCEL_URL hostname, not the project's custom domain. Deployment Protection on that hostname can reject Gateway callbacks with HTTP 401 even when the custom domain is public. Test video generation on a deployment where protection does not block the Workflow webhook endpoint.
Examples:
/storytime
/storytime --video
/storytime --video --video-duration 8
/storytime --video --style claymation
/storytime --video -t Pirates -t Space
/storytime --video --video-model klingai/kling-v3.0-t2v
/storytime -t Pirates
/storytime -t Pirates -t Space
/storytime -t Magic -t Dragons -t Friendship
/storytime -t Adventure -m anthropic/claude-sonnet-4
/storytime -t Fantasy -s "Dr. Seuss"
/storytime -s "coloring book"
/storytime -p 8
/storytime -t Pirates -s watercolor -p 6
Development
Local Testing
The included local.ts script allows you to test the core story generation logic locally without using Slack or Vercel Workflows.
# Default (2 random themes)
pnpm tsx local.ts
# With custom themes
pnpm tsx local.ts -t Pirates -t Space
# With custom model
pnpm tsx local.ts -t Magic -m anthropic/claude-sonnet-4The local script accepts the same --theme, --model, --image-model, --style (including -s), and --panels flags as the Slack command. It also accepts --transcripts to record Gateway request transcripts, which requires transcripts enabled in your team's AI Gateway settings.
The local script does not support --video, which needs a running Workflow runtime and a publicly reachable webhook. Test video generation through the Slack command instead.
Run the automated tests with pnpm test.