Skip to content

Serverless Code Commands · Developers

Write and run serverless JavaScript code directly in Dailybot. Build custom commands without deploying your own infrastructure.

Serverless Code Commands

Serverless code commands let you write and execute JavaScript code directly within Dailybot — no server infrastructure required. Your code runs in Dailybot's secure runtime environment and can make HTTP requests, access persistent storage, and return interactive responses.

Running a Command

Serverless commands can be triggered in three ways:

  1. In-Chat Trigger — Users type the command directly in DMs or channels
  2. Workflow Trigger — Code runs in response to events or schedules via Dailybot Workflows
  3. Command Scheduler — Use the Dailybot SDK to schedule a future run of the command

Command Input

When a command is triggered, your code receives an event object with context about the execution.

Query String

Additional text typed after the command name is available asevent.query. For example, typing /growth_rate July, Augustmakes "July, August" available via event.query.

Context Variables

  • event.data.intent — The triggered command name
  • event.data.user_full_name — Name of the triggering user
  • event.data.targetChannel — Chat channel object where the command executed
Parsing command input
// Parse query string input
let query = event.query;
let month = null;
if (query) {
  let parts = query.split(" ");
  if (parts[0]) {
    month = parts[0];
  }
}

return `Generating report for ${month || 'this month'}...`;

Using Serverless Code in Workflows

When the same code runs as a step inside a Dailybot Workflow(Automation), the execution context is different from a chat command. Instead of the chat event fields, your code reads automation data through a workflow object.

  • workflow.prev_step — Data returned by the previous step (e.g. workflow.prev_step.result, workflow.prev_step.ai_response)
  • workflow.action1workflow.actionN — Data returned by a step at a specific position (e.g. workflow.action1.result)
  • workflow.context — Metadata about this run (workflow_uuid, workflow_name, organization_uuid, …)

The value you return becomes prev_step.result(and actionN.result) for the steps that follow.

Reading workflow step data
// Read the output of previous steps and pass a value forward
const previous = workflow.prev_step.result;
const aiText = workflow.action1.ai_response;

return `Previous step said: ${previous}`;

Info

There is no automation object — always read step data through workflow. Inside a workflow the DailybotSDKstorage is scoped to the workflow automatically, so you don't callsetAPIKey.

Making HTTP Requests

The request variable is available in your code and wraps the superagentlibrary for making HTTP requests.

HTTP requests with superagent
// GET request
const response = await request.get('https://api.example.com/data');
const data = response.body;

// POST request with JSON body
const response = await request
  .post('https://api.example.com/submit')
  .send({ name: 'Dailybot', type: 'automation' })
  .set('Authorization', 'Bearer your-token');

Returning Results

String Response

Return a simple string to display as the command response:

javascript
return "Hello world!";

JSON Response with Interactive Buttons

Return a JSON object with a message and interactive buttons:

Interactive button response
return {
  "message": "Last week sales increased by 15% 📈",
  "buttons": [
    {
      "label": "Last month",
      "label_after_click": "Getting sales from last month...",
      "value": "sales last month",
      "button_type": "Command"
    },
    {
      "label": "Last quarter",
      "label_after_click": "Getting quarterly report...",
      "value": "sales last quarter",
      "button_type": "Command"
    }
  ]
};

Tip

Button values can reference the same command with different query parameters, enabling multi-step interactive workflows from a single command.

Dailybot SDK

The DailybotSDK object is available in your code and provides access to persistent key-value storage.

Initialization

SDK initialization
DailybotSDK.setAPIKey("your_api_key");

Key-Value Storage

Store JSON objects in user-scoped keys. Data is associated with the user making the request.

Key-value storage operations
// Write data
await DailybotSDK.Storage.write('preferences', {
  theme: 'dark',
  notifications: true
});

// Read data
let prefs = await DailybotSDK.Storage.read('preferences');
// prefs = { theme: 'dark', notifications: true }

// Delete data
await DailybotSDK.Storage.delete('preferences');

Examples

Meeting Room Booking

Meeting room booking command
// Usage: /book-room conference-a 2026-02-15 14:00
const parts = event.query.split(" ");
const roomName = parts[0];
const date = parts[1];
const time = parts[2];

if (!roomName || !date || !time) {
  return "Usage: /book-room <room-name> <date> <time>";
}

// Book the room via external API
const response = await request
  .post('https://rooms.company.com/api/book')
  .send({ room: roomName, date, time });

return `Booked ${roomName} on ${date} at ${time}. Confirmation: ${response.body.id}`;

Tech News Fetcher

Tech news fetcher command
// Fetch latest tech headlines
try {
  const response = await request
    .get('https://newsapi.org/v2/top-headlines')
    .query({ category: 'technology', pageSize: 5, apiKey: 'your_api_key' });

  const headlines = response.body.articles
    .map((a, i) => `${i + 1}. ${a.title}`)
    .join('\n');

  return `Today's Tech Headlines:\n${headlines}`;
} catch (error) {
  return "Could not fetch news. Please try again later.";
}

Advanced Patterns

  • Use SDK storage to build stateful workflows across multiple command invocations
  • Parse event.query to accept subcommands (e.g., /tool help, /tool status)
  • Chain commands using interactive buttons for multi-step processes
  • Handle errors gracefully and return helpful messages to users
  • Use the scheduler to set up recurring data fetches or reports