Skip to content

Commit

Permalink
fix: update plugin for successful build and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
boolkeys committed Jan 21, 2025
1 parent d51ab66 commit 9e54736
Show file tree
Hide file tree
Showing 32 changed files with 3,177 additions and 50 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@biomejs/biome": "^1.9.4",
"@commitlint/cli": "18.6.1",
"@commitlint/config-conventional": "18.6.3",
"@elizaos/plugin-twilio": "workspace:*",
"@types/jest": "^29.5.11",
"concurrently": "9.1.0",
"cross-env": "7.0.3",
Expand Down Expand Up @@ -55,17 +56,18 @@
"@0glabs/0g-ts-sdk": "0.2.1",
"@coinbase/coinbase-sdk": "0.10.0",
"@deepgram/sdk": "^3.9.0",
"@elizaos/plugin-0x": "link:packages/plugin-0x",
"@injectivelabs/sdk-ts": "^1.14.33",
"@vitest/eslint-plugin": "1.0.1",
"amqplib": "0.10.5",
"bs58": "4.0.0",
"csv-parse": "5.6.0",
"langdetect": "^0.2.1",
"ollama-ai-provider": "0.16.1",
"optional": "0.1.4",
"pnpm": "9.14.4",
"sharp": "0.33.5",
"tslog": "4.9.3",
"bs58": "4.0.0"
"tslog": "4.9.3"
},
"packageManager": "[email protected]+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee",
"workspaces": [
Expand Down
19 changes: 19 additions & 0 deletions packages/plugin-twilio/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Required Twilio settings
TWILIO_ACCOUNT_SID=your_account_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_PHONE_NUMBER=your_twilio_phone_number
TWILIO_CHARACTER=character.json

# Required for voice features
WEBHOOK_PORT=3004
WEBHOOK_BASE_URL=your_ngrok_url

# Optional - for voice quality
ELEVENLABS_XI_API_KEY=your_key

# Optional ElevenLabs configuration
# ELEVENLABS_MODEL_ID=eleven_monolingual_v1
# ELEVENLABS_VOICE_ID=your_voice_id
# ELEVENLABS_VOICE_STABILITY=0.5
# ELEVENLABS_VOICE_SIMILARITY_BOOST=0.9
# ELEVENLABS_VOICE_STYLE=0.66
6 changes: 6 additions & 0 deletions packages/plugin-twilio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dist/
node_modules/
.turbo/
pnpm-lock.yaml
docs/
../../characters/
198 changes: 198 additions & 0 deletions packages/plugin-twilio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# @elizaos/plugin-twilio

A Twilio plugin for ElizaOS that enables SMS and voice call capabilities.

## Features

- 📱 SMS Messaging
- Send SMS messages
- Receive and respond to SMS messages
- Natural conversation handling

- 📞 Voice Calls
- Make outgoing calls
- Receive incoming calls
- Natural voice conversations using ElevenLabs
- Speech recognition and response

## Installation

```bash
pnpm add @elizaos/plugin-twilio
```

## Configuration

1. Add the plugin to your character file:
```json
{
"name": "your_character",
"plugins": ["@elizaos/plugin-twilio"],
"settings": {
"actions": {
"enabled": ["sms", "call"]
},
"voice": {
"elevenlabs": {
"voiceId": "your_voice_id",
"stability": 0.3,
"similarityBoost": 0.5,
"style": 0.5,
"useSpeakerBoost": false
}
}
}
}
```

2. Set up environment variables in your `.env` file:

```env
# Twilio Configuration
TWILIO_ACCOUNT_SID=your_account_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_PHONE_NUMBER=your_twilio_phone_number
TWILIO_CHARACTER=character.json
# Webhook Configuration
WEBHOOK_PORT=3004
WEBHOOK_BASE_URL=your_webhook_url
# ElevenLabs (for voice synthesis)
ELEVENLABS_XI_API_KEY=your_elevenlabs_api_key
```

### Webhook Configuration

1. Set up your webhook base URL in `.env`:
```env
WEBHOOK_BASE_URL=your_webhook_url # e.g., https://your-domain.com
WEBHOOK_PORT=3004
```

2. Configure webhooks in Twilio Console:
- Go to [Twilio Console](https://console.twilio.com)
- Navigate to Phone Numbers > Manage > Active numbers
- Select your Twilio phone number
- Under "Voice & Fax" configuration:
- Set "A Call Comes In" webhook to: `[WEBHOOK_BASE_URL]/webhook/voice`
- Method: HTTP POST
- Under "Messaging" configuration:
- Set "A Message Comes In" webhook to: `[WEBHOOK_BASE_URL]/webhook/sms`
- Method: HTTP POST

Example webhook URLs:
```
Voice: https://your-domain.com/webhook/voice
SMS: https://your-domain.com/webhook/sms
```

For local development:
1. Use ngrok to expose your local server:
```bash
ngrok http 3004
```
2. Update your `WEBHOOK_BASE_URL` with the ngrok URL
3. Update webhook URLs in Twilio Console with the ngrok URL

## Security

### Environment Variables
- Never commit `.env` files to version control
- Use secrets management in production (AWS Secrets Manager, Vault)
- Rotate credentials regularly
- Use environment-specific configurations

### Webhook Security
- Enable Twilio's request validation
- Use HTTPS for webhook endpoints
- Implement rate limiting
- Set up IP allowlisting for Twilio IPs
- Monitor webhook access logs

## Usage

### Interacting with the Agent

You can interact with the agent in two ways:

#### Via SMS
1. Save the Twilio phone number: {TWILIO_PHONE_NUMBER}
2. Send a text message to start a conversation
3. The agent will respond based on its character configuration
4. Continue the natural conversation via SMS

#### Via Voice Call
1. Call the Twilio phone number: {TWILIO_PHONE_NUMBER}
2. The agent will answer and start a conversation
3. Speak naturally - the agent uses speech recognition
4. The agent will respond with natural voice using ElevenLabs

### Sending Messages Through the Agent

Best Practices:
1. For direct messages, use "saying" or "telling"
2. For AI-generated content, use "about"
3. Always include the full phone number with "+" prefix
4. Keep messages concise (160 char limit)

#### SMS Commands

```
Send an SMS to +1234567890 saying Hello world!
Send SMS to +1234567890 about the weather forecast
```

#### Voice Call Commands

```
Call +1234567890 and tell them about the latest updates
Call +1234567890 to say that we need to schedule a meeting
```

## Development

```bash
# Install dependencies
pnpm install

# Build the plugin
pnpm build
```

## Webhook Setup

For local development, use ngrok or similar to expose your webhook:

```bash
ngrok http 3004
```

Then update your `WEBHOOK_BASE_URL` in `.env` with the ngrok URL.

## Notes

- Voice calls require ElevenLabs API key for text-to-speech
- Uses Twilio's built-in speech recognition capabilities for speech-to-text
- Messages are limited to 160 characters for SMS
- Voice responses are optimized for natural conversation flow
- All phone numbers must be in international format (+1234567890)
- The agent's responses are based on its configured character personality
- Incoming messages and calls are handled automatically through webhooks

## Important: A2P 10DLC Registration

If you're using US phone numbers (+1) for SMS messaging, you must complete A2P 10DLC registration:

- **Brand Registration**: Required one-time process through Twilio's Trust Hub
- **Campaign Registration**: Required for AI chatbot/automated messaging use case
- **Messaging Service**: Must link campaign to a Messaging Service with your phone numbers

Note: Voice-only functionality does not require A2P registration. Registration is mandatory for any SMS functionality to US numbers as of September 1, 2023.

See [Twilio's A2P 10DLC Documentation](https://www.twilio.com/docs/messaging/compliance/a2p-10dlc) for registration process.

## License

This plugin is part of the Eliza project. See the main project repository for license information.

45 changes: 45 additions & 0 deletions packages/plugin-twilio/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@elizaos/plugin-twilio",
"version": "0.1.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js",
"default": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"clean": "rimraf dist",
"prebuild": "pnpm clean",
"build": "tsup --format esm",
"dev": "tsc -w"
},
"dependencies": {
"@elizaos/core": "workspace:*",
"express": "^4.x.x",
"twilio": "^4.x.x",
"uuid": "^9.0.0",
"elevenlabs-node": "^2.0.0",
"express-rate-limit": "^7.1.5"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^20.0.0",
"@types/uuid": "^9.0.0",
"esbuild": "^0.19.0",
"glob": "^10.0.0",
"rimraf": "^5.0.5",
"tsx": "^4.7.0",
"typescript": "^5.0.0",
"@types/twilio": "^3.19.3",
"vitest": "^1.0.0",
"@vitest/coverage-v8": "^1.0.0"
}
}
70 changes: 70 additions & 0 deletions packages/plugin-twilio/scripts/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { build } from 'esbuild';
import { glob } from 'glob';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { rm } from 'fs/promises';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

const __dirname = dirname(fileURLToPath(import.meta.url));

async function buildPlugin() {

// Clean previous build
console.log('🧹 Cleaning previous build...');
await rm('dist', { recursive: true, force: true });

// run TypeScript type checking
console.log('🔍 Running TypeScript type checking...');
try {
await execAsync('tsc --noEmit');
} catch (error) {
console.error('❌ TypeScript type checking failed:', error.stdout);
process.exit(1);
}

console.log('🔍 Finding source files...');
const entryPoints = await glob('src/**/*.ts', {
cwd: dirname(__dirname),
absolute: true,
});
console.log(`📁 Found ${entryPoints.length} files to build`);

try {
console.log('🚀 Starting build...');
await build({
entryPoints,
outdir: 'dist',
platform: 'node',
format: 'esm',
target: 'node18',
bundle: true,
sourcemap: true,
external: [
'@elizaos/core',
'twilio',
'express',
'uuid',
'express-rate-limit'
],
logLevel: 'info',
mainFields: ['module', 'main'],
banner: {
js: '// @ts-check\n'
},
outExtension: { '.js': '.js' }
});

console.log('✅ Build completed successfully');
} catch (error) {
console.error('❌ Build failed:', error);
process.exit(1);
}
}

buildPlugin().catch(err => {
console.error('❌ Unhandled error:', err);
process.exit(1);
});
21 changes: 21 additions & 0 deletions packages/plugin-twilio/scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": ".",
"strict": true,
"skipLibCheck": true
},
"include": [
"*.ts",
"*.mts"
],
"exclude": [
"../src",
"../dist",
"../node_modules"
]
}
Loading

0 comments on commit 9e54736

Please sign in to comment.