# Serverless commands

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

Language: en
Canonical: https://www.dailybot.com/developers/serverless
Markdown: send header `Accept: text/markdown` on any URL to receive Markdown instead of HTML.
Last Updated: 2026-04-06

---

# 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 as `event.query`. For example, typing `/growth_rate July, August` makes `"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

```javascript
// 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.action1` … `workflow.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.

```javascript
// 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}`;
```

> **Note:** There is no `automation` object — always read step data through `workflow`. Inside a workflow the `DailybotSDK` storage is scoped to the workflow automatically, so you don't call `setAPIKey`.

## Making HTTP requests

The `request` variable is available in your code and wraps the [superagent](https://github.com/ladjs/superagent) library for making HTTP requests.

```javascript
// 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:

```javascript
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

```javascript
DailybotSDK.setAPIKey("your_api_key");
```

### Key-value storage

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

```javascript
// 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

```javascript
// 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

```javascript
// 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

---

## Developer portal navigation

**Getting Started**

- [Overview](/developers)
- [Quick start](/developers/getting-started)
- [Authentication](/developers/authentication)

**API Reference**

- [API Overview](/developers/api)
- [Users](/developers/api/users)
- [Organization](/developers/api/organization)
- [Teams](/developers/api/teams)
- [Invitations](/developers/api/invitations)
- [Check-ins](/developers/api/check-ins)
- [Forms](/developers/api/forms)
- [Report channels](/developers/api/report-channels)
- [Templates](/developers/api/templates)
- [Kudos](/developers/api/kudos)
- [Mood tracking](/developers/api/mood)
- [Important dates](/developers/api/important-dates)
- [Messaging](/developers/api/messaging)
- [Automations](/developers/api/workflows)
- [Webhooks](/developers/api/webhooks)
- [Commands platform](/developers/api/commands-platform)
- [Agents](/developers/api/agents)
- [OAuth2](/developers/api/oauth2)
- [Integrations](/developers/api/integrations)
- [CLI](/developers/api/cli)

**API guides**

- [Errors & Status Codes](/developers/errors)
- [Rate Limits](/developers/rate-limits)
- [Conventions](/developers/conventions)
- [API Changelog](/developers/api-changelog)
- [Recipes](/developers/recipes)

**Developer Features**

- [Custom commands](/developers/custom-commands)
- [Serverless commands](/developers/serverless) (this page)
- [Webhooks & events](/developers/webhooks)
- [Automation API trigger](/developers/workflow-trigger)
- [Activity API](/developers/activity-api)

**CLI**

- [Overview](/developers/cli)
- [Authentication](/developers/cli-authentication)
- [Command reference](/developers/cli-reference)
- [CI/CD recipes](/developers/cli-ci-cd)
- [Configuration](/developers/cli-configuration)
- [Troubleshooting](/developers/cli-troubleshooting)

**Agent Skill**

- [Overview](/developers/agent-skill)
- [Skills catalog](/skills)

---

## Site navigation

**Product:**
- [Home](/)
- [Product](/product)
- [Pricing](/pricing)
- [Enterprise](/enterprise)
- [Integrations](/integrations)
- [Templates](/templates)

**Resources:**
- [Blog](/blog)
- [Academy](/academy)
- [Changelog](/changelog)
- [Help Center](/help)
- [Developers](/developers)
- [Agents](/agents)

**Company:**
- [About](/about)
- [Careers](/careers)
- [Security](/security)
- [Contact Sales](/demo)

**Connect:**
- [LinkedIn](https://www.linkedin.com/company/dailybot/)
- [X/Twitter](https://twitter.com/dailybot)
- [GitHub](https://github.com/Dailybot-Inc)
- [YouTube](https://www.youtube.com/channel/UC3uM9V52vwX7e3vQpCc4qvA)

