npm package: @openpets/bento
Description: Bento email marketing platform integration - manage subscribers, track events, send broadcasts, and analyze engagement
Latest version: 1.0.6

# Bento Plugin for OpenCode

Comprehensive integration with [Bento](https://bentonow.com) email marketing and analytics platform. Manage subscribers, track events, send broadcasts, and analyze engagement using the official Bento Node SDK.

## Features

### Subscriber Management
- Add, update, and retrieve subscribers
- Upsert subscribers (create or update)
- Batch import subscribers
- Unsubscribe users

### Event Tracking
- Track custom events with details
- Track purchases for LTV calculation
- Batch import events
- Custom event properties and fields

### Tag & Field Management
- Create and manage tags
- Add/remove tags from subscribers
- Create and manage custom fields
- Update field values

### Email Broadcasting
- Get all broadcast campaigns
- Create new broadcast campaigns
- Target by tags and segments
- Throttle sending rates

### Transactional Emails
- Send individual or batch transactional emails
- Liquid template support
- Personalization variables
- Override unsubscribe status (for critical emails)

### Analytics & Statistics
- Get overall site statistics
- Segment performance metrics
- Broadcast report analytics
- Subscriber growth tracking

### Experimental Features
- Email validation
- IP geolocation
- Blacklist checking
- Content moderation
- Gender guessing from names

### Commands API (No Automations)
- Update tags without triggering automations
- Update fields without triggering automations
- Useful for data cleanup and migrations

## Prerequisites

1. A Bento account at [app.bentonow.com](https://app.bentonow.com)
2. Node.js version 18 or later
3. Bento API credentials (see Setup section)

## Setup

### 1. Get Your Bento Credentials

1. Log into your Bento account at [app.bentonow.com](https://app.bentonow.com)
2. Navigate to **Settings → API Keys**
3. Copy the following:
   - **Publishable Key** (starts with `bento_pk_`)
   - **Secret Key** (starts with `bento_sk_`)
   - **Site UUID** (your site identifier)

### 2. Configure Environment Variables

```bash
cp .env.example .env
```

Edit `.env` and add your credentials:

```bash
BENTO_PUBLISHABLE_KEY=bento_pk_your_publishable_key_here
BENTO_SECRET_KEY=bento_sk_your_secret_key_here
BENTO_SITE_UUID=your_site_uuid_here
```

### 3. Install Dependencies

```bash
npm install
# or
pnpm install
```

### 4. Test the Plugin

```bash
npm run quickstart
# or
opencode run "get site statistics"
```

## Using from Other Projects

Add to your project's `opencode.json`:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "/absolute/path/to/bento/index.ts"
  ]
}
```

## Available Tools

### Subscriber Management Tools

#### add-subscriber
Add a new subscriber to Bento (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address
- `firstName` (optional): First name
- `lastName` (optional): Last name
- `fields` (optional): Additional custom fields as key-value pairs

**Example:**
```bash
opencode run "add subscriber john.doe@example.com with firstName John and lastName Doe"
```

#### upsert-subscriber
Create or update a subscriber in Bento.

**Parameters:**
- `email` (required): Subscriber email address
- `fields` (optional): Custom fields to set
- `tags` (optional): Comma-separated tags to add
- `removeTags` (optional): Comma-separated tags to remove

**Example:**
```bash
opencode run "upsert subscriber jane@example.com with tags premium,vip"
```

#### get-subscriber
Get subscriber details by email or UUID.

**Parameters:**
- `email` (optional): Subscriber email address
- `uuid` (optional): Subscriber UUID

**Example:**
```bash
opencode run "get subscriber john.doe@example.com"
```

#### update-fields
Update custom fields for a subscriber (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address
- `fields` (required): Fields to update as key-value pairs

**Example:**
```bash
opencode run "update fields for user@example.com set lastLogin to today"
```

#### remove-subscriber
Unsubscribe a subscriber (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address

**Example:**
```bash
opencode run "remove subscriber user@example.com"
```

#### batch-import-subscribers
Import multiple subscribers in a single operation.

**Parameters:**
- `subscribers` (required): Array of subscriber objects with email, firstName, lastName, and fields

**Example:**
```bash
opencode run "batch import 3 subscribers from this list: john@example.com, jane@example.com, bob@example.com"
```

### Event Tracking Tools

#### track-event
Track a custom event for a subscriber (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address
- `type` (required): Event type (e.g., $pageView, $login, custom-event)
- `details` (optional): Event details/properties
- `fields` (optional): Fields to update on subscriber

**Example:**
```bash
opencode run "track event $pageView for user@example.com with url /products"
```

#### track-purchase
Track a purchase event to calculate subscriber LTV (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address
- `orderKey` (required): Unique order identifier
- `amount` (required): Purchase amount in cents (e.g., 1000 = $10.00)
- `currency` (optional, default: USD): Currency code
- `cartItems` (optional): Array of cart items with productId, productName, quantity, price

**Example:**
```bash
opencode run "track purchase for user@example.com order ORD-123 amount 9999 cents"
```

### Tag Management Tools

#### tag-subscriber
Add a tag to a subscriber (TRIGGERS automations).

**Parameters:**
- `email` (required): Subscriber email address
- `tagName` (required): Tag name to add

**Example:**
```bash
opencode run "tag subscriber user@example.com with Premium Customer"
```

#### get-tags
Get all tags in the Bento account.

**Example:**
```bash
opencode run "get all tags"
```

#### create-tag
Create a new tag in Bento.

**Parameters:**
- `name` (required): Tag name

**Example:**
```bash
opencode run "create tag VIP Customer"
```

### Field Management Tools

#### get-fields
Get all custom fields defined in Bento.

**Example:**
```bash
opencode run "get all fields"
```

#### create-field
Create a new custom field in Bento.

**Parameters:**
- `key` (required): Field key/name

**Example:**
```bash
opencode run "create field loyaltyPoints"
```

### Broadcasting Tools

#### get-broadcasts
Retrieve all broadcast campaigns.

**Example:**
```bash
opencode run "get all broadcasts"
```

#### create-broadcast
Create new broadcast campaign(s).

**Parameters:**
- `broadcasts` (required): Array of broadcast objects with:
  - `name`: Broadcast name
  - `subject`: Email subject
  - `content`: HTML content
  - `type`: Content type (html or plain)
  - `fromName`: Sender name
  - `fromEmail`: Sender email
  - `inclusiveTags` (optional): Comma-separated tags to include
  - `exclusiveTags` (optional): Comma-separated tags to exclude
  - `segmentId` (optional): Segment ID to send to
  - `batchSizePerHour` (optional): Throttle rate per hour

**Example:**
```bash
opencode run "create broadcast Weekly Newsletter subject 'Your Update' from John at john@company.com"
```

### Transactional Email Tools

#### send-transactional-email
Send transactional email(s) via Bento.

**Parameters:**
- `emails` (required): Array of 1-100 email objects with:
  - `to`: Recipient email
  - `from`: Sender email (must be existing Author in Bento)
  - `subject`: Email subject (supports liquid templates)
  - `htmlBody`: HTML email content (supports liquid templates)
  - `transactional`: Send to unsubscribed users (default: false)
  - `personalizations` (optional): Liquid template variables

**Example:**
```bash
opencode run "send transactional email to user@example.com from support@company.com subject 'Welcome' with name John"
```

**Important:** The `from` email must be an existing Author in your Bento account. Add authors at Settings → Authors in the Bento dashboard.

### Analytics Tools

#### get-site-stats
Get overall site statistics including subscribers and engagement.

**Example:**
```bash
opencode run "get site statistics"
```

#### get-segment-stats
Get statistics for a specific segment.

**Parameters:**
- `segmentId` (required): Segment ID to get stats for

**Example:**
```bash
opencode run "get segment stats for segment_123"
```

#### get-report-stats
Get statistics for a specific broadcast report.

**Parameters:**
- `reportId` (required): Report ID to get stats for

**Example:**
```bash
opencode run "get report stats for report_456"
```

### Form Tools

#### get-form-responses
Get responses for a specific form.

**Parameters:**
- `formId` (required): Form ID

**Example:**
```bash
opencode run "get form responses for form_789"
```

### Experimental Tools

#### validate-email
Validate an email address (Experimental).

**Parameters:**
- `email` (required): Email to validate
- `ip` (optional): IP address
- `name` (optional): Name
- `userAgent` (optional): User agent string

**Example:**
```bash
opencode run "validate email test@example.com"
```

#### geolocate-ip
Get geolocation information for an IP address (Experimental).

**Parameters:**
- `ip` (required): IP address to geolocate

**Example:**
```bash
opencode run "geolocate IP 192.168.1.1"
```

#### check-blacklist
Check if a domain or IP is blacklisted (Experimental).

**Parameters:**
- `domain` (optional): Domain to check
- `ipAddress` (optional): IP address to check

**Example:**
```bash
opencode run "check blacklist for domain example.com"
```

#### moderate-content
Perform content moderation on text (Experimental).

**Parameters:**
- `content` (required): Content to moderate

**Example:**
```bash
opencode run "moderate content 'This is a test message'"
```

#### guess-gender
Attempt to guess gender from a name (Experimental).

**Parameters:**
- `name` (required): Name to analyze

**Example:**
```bash
opencode run "guess gender for name Alex"
```

### Commands API Tools (No Automations)

These tools use the Commands API and do NOT trigger automations. Use these for data cleanup, migrations, or when you want to update data without triggering workflows.

#### add-tag-no-automation
Add tag to subscriber WITHOUT triggering automations.

**Parameters:**
- `email` (required): Subscriber email
- `tagName` (required): Tag name

**Example:**
```bash
opencode run "add tag Premium to user@example.com without automation"
```

#### remove-tag-no-automation
Remove tag from subscriber WITHOUT triggering automations.

**Parameters:**
- `email` (required): Subscriber email
- `tagName` (required): Tag name

**Example:**
```bash
opencode run "remove tag Trial from user@example.com without automation"
```

#### add-field-no-automation
Add field to subscriber WITHOUT triggering automations.

**Parameters:**
- `email` (required): Subscriber email
- `key` (required): Field key
- `value` (required): Field value

**Example:**
```bash
opencode run "add field migrated with value true to user@example.com without automation"
```

#### remove-field-no-automation
Remove field from subscriber WITHOUT triggering automations.

**Parameters:**
- `email` (required): Subscriber email
- `fieldName` (required): Field name to remove

**Example:**
```bash
opencode run "remove field tempData from user@example.com without automation"
```

## Important Concepts

### Automations vs. Commands

**V1 Methods (Triggers Automations):**
- `add-subscriber`, `tag-subscriber`, `update-fields`, `track-event`, etc.
- Use the Batch API
- **Takes 1-3 minutes** to appear in Bento
- **Triggers automations** when data changes
- Best for real-time user interactions

**Commands API (No Automations):**
- `add-tag-no-automation`, `add-field-no-automation`, etc.
- Direct API operations
- **Instant** updates
- **Does NOT trigger automations**
- Best for data migrations and cleanup

### Event Timing

Batch operations (most V1 methods) use Bento's batch import API, which processes events asynchronously. Events typically appear within 1-3 minutes.

### Purchase Amounts

All purchase amounts should be in cents. For example:
- $10.00 = 1000 cents
- $99.99 = 9999 cents

### Liquid Templates

Transactional emails and broadcast subjects/content support Liquid templates:

```liquid
Hello {{ name }},

Your order {{ order_id }} is confirmed.

Total: {{ total_amount | money }}
```

Pass template variables in the `personalizations` field.

## Configuration

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `BENTO_PUBLISHABLE_KEY` | Yes | Bento publishable API key |
| `BENTO_SECRET_KEY` | Yes | Bento secret API key |
| `BENTO_SITE_UUID` | Yes | Bento site UUID |

## Error Handling

All tools return JSON responses with the following structure:

**Success:**
```json
{
  "success": true,
  "data": { ... },
  "message": "Operation completed successfully"
}
```

**Error:**
```json
{
  "success": false,
  "error": "Error message describing what went wrong"
}
```

## Common Issues

### "Missing required Bento credentials"
Make sure all three environment variables are set in your `.env` file.

### "Author not found" (Transactional Emails)
The `from` email must be added as an Author in your Bento account:
1. Go to Settings → Authors in Bento
2. Add the email address you want to send from
3. Verify the email if required

### Events not appearing
Batch operations take 1-3 minutes to process. Check the Bento dashboard after a few minutes.

### Rate Limits
Bento may rate limit API requests. The SDK handles most errors gracefully, but very high-volume operations should be throttled on your end.

## API Reference

This plugin uses a custom client implementation based on the official [Bento Node SDK](https://github.com/bentonow/bento-node-sdk), providing direct API access without external dependencies.

For detailed API documentation, visit:
- [Bento Documentation](https://docs.bentonow.com)
- [Subscribers API](https://docs.bentonow.com/subscribers)
- [API Reference](https://docs.bentonow.com/api-reference)

## Support

- **Plugin Issues:** [OpenPets GitHub Issues](https://github.com/raggle-ai/pets/issues)
- **Bento Support:** [Discord](https://discord.gg/ssXXFRmt5F) or email jesse@bentonow.com
- **Documentation:** [docs.bentonow.com](https://docs.bentonow.com)

## License

MIT