-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: update plugin for successful build and tests
- Loading branch information
Showing
32 changed files
with
3,177 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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", | ||
|
@@ -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": [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dist/ | ||
node_modules/ | ||
.turbo/ | ||
pnpm-lock.yaml | ||
docs/ | ||
../../characters/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
] | ||
} |
Oops, something went wrong.