Skip to content

Commit 1cb3af7

Browse files
committed
added plugin-twilio this can send message using sms or whatsapp
1 parent cb5de7a commit 1cb3af7

10 files changed

+468
-0
lines changed

packages/plugin-twilio/.npmignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*
2+
3+
!dist/**
4+
!package.json
5+
!readme.md
6+
!tsup.config.ts

packages/plugin-twilio/ReadMe.txt

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#The ENV file should contain this information
2+
3+
# Cache Configs
4+
CACHE_STORE=database
5+
6+
# Discord Configuration
7+
DISCORD_APPLICATION_ID=
8+
DISCORD_API_TOKEN=
9+
10+
# AI Model API Keys
11+
OPENAI_API_KEY=
12+
13+
# Twitter/X Configuration
14+
TWITTER_USERNAME=
15+
TWITTER_PASSWORD=
16+
TWITTER_EMAIL=
17+
TWITTER_POLL_INTERVAL=120 # How often (in seconds) the bot should check for interactions
18+
TWITTER_SEARCH_ENABLE=FALSE # Enable timeline search, WARNING this greatly increases your chance of getting banned
19+
#TWITTER_TARGET_USERS=
20+
21+
# Twilio Part
22+
TWILIO_ACCOUNT_SID=
23+
TWILIO_AUTH_TOKEN=
24+
TWILIO_PHONE_NUMBER=
25+
TWILIO_WHATSAPP_PHONE_NUMBER=
26+
27+
# Server Configuration
28+
SERVER_PORT=3000
29+
30+
# How to use
31+
1. create your .env file , if you don't have it yet and then populate it with the information above, make sure to fill in all information
32+
2. Add this project into your eliza os project under packages
33+
3. using terminal go inside plugin-twilio then type pnpm install twilio
34+
4. go inside your agent folder update the package.json add this "@elizaos/plugin-twilio": "workspace:*"
35+
5. add this inside your Agent index.ts import { twilioPlugin } from "@elizaos/plugin-twilio";
36+
6. Add twilioPlugin in Agent Runtime still inside Agent index.ts
37+
7. pnpm install
38+
8. pnpm build
39+
9. pmpn start --character="characters/nameofyouragentcharacterfile.character.json"
40+
41+
#Note: Make sure you have a twilio developer account and it is verified with verified phone number and have enough credits but they provide free small credits when your account is new
42+
visit twilio: https://www.twilio.com
43+
twilio quick start guides: https://www.twilio.com/docs/messaging/quickstart
44+
twilio documentation: https://www.twilio.com/docs/messaging
45+
Free Trial Account: https://www.twilio.com/docs/messaging/guides/how-to-use-your-free-trial-account
46+
47+
# For WhatsApp guides follow the link below you need to have a separate twilio whatsapp enabled phone number
48+
https://www.twilio.com/docs/whatsapp
49+
https://www.twilio.com/docs/whatsapp/quickstart/node
50+
https://www.twilio.com/docs/whatsapp/getting-started#registering-a-whatsapp-sender
51+
https://www.twilio.com/docs/verify/whatsapp
52+
53+
54+
#Some Other Whats App Info that you might need
55+
https://www.twilio.com/docs/whatsapp
56+
57+
#Twilio Phone Number guidelines
58+
https://www.twilio.com/en-us/guidelines
59+
60+
61+
# Clarification this project is intended to be use/place inside elizaos project packages, this can't work alone
62+
63+
# Sample implementation can be found here
64+
https://github.com/juanc07/AgentSoulSpark
65+
66+
# Usage Sample
67+
68+
The message that you want to send must be inside a Single Quote or double quotes
69+
70+
Example 1:
71+
Please send sms to [phone number], and my message is '[your message here]'
72+
Please send whats app message to [phone number], and my message is '[your message here]'
73+
74+
Example 2:
75+
Please send sms to [phone number], and my message is "[your message here]"
76+
Please send whats app message to [phone number], and my message is "[your message here]"
77+
78+
#Note I haven't tested any other complex string or sentence yet, this could be improve ofcourse but for now it works that way
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import eslintGlobalConfig from "../../eslint.config.mjs";
2+
3+
export default [...eslintGlobalConfig];

packages/plugin-twilio/package.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@elizaos/plugin-twilio",
3+
"version": "0.1.7-alpha.2",
4+
"main": "dist/index.js",
5+
"type": "module",
6+
"types": "dist/index.d.ts",
7+
"dependencies": {
8+
"@elizaos/core": "workspace:*",
9+
"tsup": "8.3.5",
10+
"twilio": "^5.4.0"
11+
},
12+
"scripts": {
13+
"build": "tsup --format esm --dts",
14+
"dev": "tsup --format esm --dts --watch",
15+
"lint": "eslint --fix --cache ."
16+
},
17+
"peerDependencies": {
18+
"whatwg-url": "7.1.0"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./helloWorld.ts";
2+
export * from "./sendSms.ts";
3+
export * from "./sendWhatsAppMessage.ts";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import {
2+
ActionExample,
3+
generateText,
4+
HandlerCallback,
5+
IAgentRuntime,
6+
Memory,
7+
ModelClass,
8+
State,
9+
type Action,
10+
} from "@elizaos/core";
11+
import twilio from 'twilio';
12+
13+
export const sendSmsAction: Action = {
14+
name: "SendSms",
15+
similes: [
16+
"SendSms"
17+
],
18+
validate: async (_runtime: IAgentRuntime, _message: Memory) => {
19+
return true;
20+
},
21+
description:
22+
"Send SMS to the mobile number provided by the user",
23+
handler: async (
24+
_runtime: IAgentRuntime,
25+
_message: Memory,
26+
_state: State,
27+
_options:{[key:string]: unknown},
28+
_callback: HandlerCallback,
29+
): Promise<boolean> => {
30+
// Check if environment variables are set
31+
const accountSid = process.env.TWILIO_ACCOUNT_SID;
32+
const authToken = process.env.TWILIO_AUTH_TOKEN;
33+
34+
console.log("CHECK _message: ",_message.content.text);
35+
36+
if (!accountSid || !authToken) {
37+
console.error('TWILIO_ACCOUNT_SID or TWILIO_AUTH_TOKEN is not set');
38+
return false;
39+
}
40+
41+
// Extract the mobile number from the message
42+
const mobileNumberRegex = /(?:\+|00)(\d{1,3})\s?(\d{3,5})\s?(\d{4,10})/; // This regex matches numbers like +1 123 4567890 or 001 123 4567890
43+
const text = (_message.content as { text?: string })?.text || '';
44+
const matches = text.match(mobileNumberRegex);
45+
46+
const messageRegex = /(['"])(.*?)\1/;
47+
const messageMatch = text.match(messageRegex);
48+
49+
let mobileNumberProvidedByUser = null;
50+
let messageToSendFromUser = null;
51+
52+
if(messageMatch){
53+
messageToSendFromUser = messageMatch[2];
54+
}
55+
if (matches) {
56+
// Combine the parts of the number into a single string, removing spaces and plus signs
57+
mobileNumberProvidedByUser = `+${matches[1]}${matches[2]}${matches[3]}`;
58+
}else{
59+
const alternativeMobileNumberRegex = /\b(\d{3})[-.]?(\d{3})[-.]?(\d{4})\b/; // For formats like 123-456-7890 or 123.456.7890
60+
if (!mobileNumberProvidedByUser) {
61+
const alternativeMatches = text.match(alternativeMobileNumberRegex);
62+
if (alternativeMatches) {
63+
mobileNumberProvidedByUser = `${alternativeMatches[1]}${alternativeMatches[2]}${alternativeMatches[3]}`;
64+
}
65+
}
66+
}
67+
68+
const twilioNumber = process.env.TWILIO_PHONE_NUMBER; // Your Twilio phone number
69+
70+
console.log('check target mobile number: ', mobileNumberProvidedByUser);
71+
console.log('check messageToSendFromUser: ', messageToSendFromUser);
72+
console.log('check twilioNumber: ', twilioNumber);
73+
74+
if (!twilioNumber) {
75+
console.error('Twilio phone number is missing');
76+
77+
_callback({
78+
text: `Sorry there was an issue send sms, please try again later`,
79+
});
80+
return false;
81+
}
82+
83+
const recentMessages = `Extract the phone number from the user recent messages ${_state.recentMessages}`;
84+
85+
if (!mobileNumberProvidedByUser) {
86+
console.error('Mobile number is missing will try to get the phone number or mobile number from recent messages');
87+
88+
mobileNumberProvidedByUser = await generateText(
89+
{
90+
runtime: _runtime,
91+
context: recentMessages,
92+
modelClass: ModelClass.SMALL,
93+
stop: ["\n"],
94+
customSystemPrompt: "only extract the message that the user intend to send and only get the last one"
95+
}
96+
);
97+
}
98+
99+
if (!mobileNumberProvidedByUser) {
100+
console.error('Mobile number is missing');
101+
102+
_callback({
103+
text: `Sorry, there was an issue send sms, please try again later`,
104+
});
105+
return false;
106+
}
107+
108+
const recentUserMessages = `Extract the message intended for SMS or text: ${_state.recentMessages}`;
109+
110+
if (!messageToSendFromUser) {
111+
console.error('messageToSendFromUser is missing will try to get the user message from recent messages');
112+
113+
messageToSendFromUser = await generateText(
114+
{
115+
runtime: _runtime,
116+
context: recentUserMessages,
117+
modelClass: ModelClass.SMALL,
118+
stop: ["\n"]
119+
}
120+
);
121+
}
122+
123+
if(messageToSendFromUser==null){
124+
console.error('messageToSendFromUser is empty or null');
125+
126+
_callback({
127+
text: `Sorry there was an issue sending the WhatsApp message, please try again later`,
128+
});
129+
return false;
130+
}
131+
132+
try {
133+
// Initialize Twilio client
134+
const client = twilio(accountSid, authToken);
135+
136+
// Send the SMS
137+
const message= await client.messages.create({
138+
body: messageToSendFromUser, // The message body
139+
to: mobileNumberProvidedByUser, // The recipient's phone number
140+
from: twilioNumber, // Your Twilio phone number
141+
});
142+
143+
console.log("message body: ", message);
144+
145+
const messageFromAgent = `SMS sent successfully to ${mobileNumberProvidedByUser}`;
146+
147+
// Call the callback to notify the user
148+
_callback({
149+
text: messageFromAgent,
150+
});
151+
152+
return true;
153+
} catch (error) {
154+
console.error('Failed to send SMS:', error);
155+
_callback({
156+
text: `Failed to send SMS to ${mobileNumberProvidedByUser}`,
157+
});
158+
return false;
159+
}
160+
},
161+
examples: [
162+
[
163+
{
164+
user: "{{user1}}",
165+
content: { text: "please send my message via sms to target mobile number" },
166+
},
167+
{
168+
user: "{{user2}}",
169+
content: { text: "", action: "SEND_SMS" },
170+
},
171+
],
172+
] as ActionExample[][],
173+
} as Action;

0 commit comments

Comments
 (0)