Skip to content

Commit ffefe40

Browse files
committed
add Twilio SMS messaging functionality
1 parent 48f8aeb commit ffefe40

7 files changed

Lines changed: 93 additions & 5 deletions

File tree

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ python setup.py
5959

6060
This will start the application with the default configuration. The frontend will be available at http://localhost:3000 and the backend at http://localhost:5007.
6161

62+
## Setting Up Twilio for SMS Alerts
63+
64+
nanoCAS supports sending SMS alerts using Twilio when a sequence of interest meets the specified coverage threshold. Since nanoCAS is open-source, you’ll need to set up your own Twilio account and configure it yourself. Follow these steps to enable SMS notifications:
65+
66+
### 1. Create a Twilio Account
67+
- Visit [Twilio's website](https://www.twilio.com/try-twilio) and sign up for a free account.
68+
- Complete the verification process by providing your email and phone number.
69+
70+
### 2. Obtain a Twilio Phone Number
71+
- Log in to your Twilio Console at [https://console.twilio.com/](https://console.twilio.com/).
72+
- Navigate to the **"Phone Numbers"** section under **"All Products & Services"**.
73+
- Click **"Buy a Number"**, search for a number that supports SMS (check the capabilities), and purchase it.
74+
- Note down your Twilio phone number (e.g., `+12345678901`).
75+
76+
### 3. Get Your Account SID and Auth Token
77+
- In the Twilio Console dashboard, locate your **"Account SID"** and **"Auth Token"** under the **"Account Info"** section.
78+
- These credentials are required to authenticate API requests. Keep them secure.
79+
80+
### 4. Configure the `.env` File
81+
- In the root directory of your nanoCAS project, create or edit the `.env` file to include the following Twilio configuration:
82+
```plaintext
83+
TWILIO_ACCOUNT_SID=your_account_sid
84+
TWILIO_AUTH_TOKEN=your_auth_token
85+
TWILIO_PHONE_NUMBER=your_twilio_phone_number
86+
ALERT_RECIPIENT_PHONE=recipient_phone_number
87+
6288
### Manual Installation
6389
6490
For environments where Docker is not available or for development purposes:

frontend/.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodejs 16.20.2

server/app/main/utils/FileHandler.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from app import socketio
1212
from .LinuxNotification import LinuxNotification
1313
from .email import send_email
14+
from .sms import send_sms
1415

1516
logger = logging.getLogger('nanocas')
1617

@@ -186,6 +187,7 @@ def calculate_and_record_coverage(self):
186187
logger.error(f"Error calculating coverage: {e}")
187188

188189
def check_breadth_alert(self, ref: str, breadth: float):
190+
"""Check if breadth exceeds threshold and send alerts."""
189191
print(f"Checking breadth alert for {ref} with breadth {breadth:.2f}%")
190192
alertinfo_cfg_file = os.path.join(self.app_loc, 'alertinfo.cfg')
191193
try:
@@ -206,16 +208,20 @@ def check_breadth_alert(self, ref: str, breadth: float):
206208
logger.critical(alert_str)
207209
if device:
208210
LinuxNotification.send_notification(device, alert_str)
211+
# Send alerts if configured
209212
if "alertNotifConfig" in alertinfo_cfg_data:
210213
print("Sending email")
211214
email_config = alertinfo_cfg_data['alertNotifConfig']
212215
subject = "nanoCAS Alert"
213216
body = alert_str
214217
send_email(subject, body, email_config)
218+
# Send SMS via Twilio if configured in .env
219+
if os.getenv('TWILIO_ACCOUNT_SID'):
220+
print("Sending SMS")
221+
send_sms(alert_str)
215222
else:
216-
print("No email config found")
217-
logger.error("No email config found in alertinfo.cfg")
218-
223+
print("Twilio not configured; skipping SMS")
224+
logger.debug("Twilio not configured in .env; SMS skipped")
219225
# Update current_breadth after checking
220226
if breadth > current_breadth:
221227
query["current_breadth"] = breadth

server/app/main/utils/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
from .LinuxNotification import LinuxNotification
1+
from .LinuxNotification import LinuxNotification
2+
from .sms import send_sms

server/app/main/utils/sms.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
from twilio.rest import Client
3+
from twilio.base.exceptions import TwilioRestException
4+
import logging
5+
from dotenv import load_dotenv
6+
7+
# Load environment variables from .env file
8+
load_dotenv()
9+
10+
logger = logging.getLogger('nanocas')
11+
12+
def send_sms(body):
13+
"""Send an SMS alert using Twilio."""
14+
account_sid = os.getenv('TWILIO_ACCOUNT_SID')
15+
auth_token = os.getenv('TWILIO_AUTH_TOKEN')
16+
twilio_phone = os.getenv('TWILIO_PHONE_NUMBER')
17+
recipient_phone = os.getenv('ALERT_RECIPIENT_PHONE')
18+
19+
# Check if all required Twilio credentials are provided
20+
if not all([account_sid, auth_token, twilio_phone, recipient_phone]):
21+
logger.error("Twilio configuration missing in .env file. SMS not sent.")
22+
return
23+
24+
try:
25+
client = Client(account_sid, auth_token)
26+
message = client.messages.create(
27+
body=body,
28+
from_=twilio_phone,
29+
to=recipient_phone
30+
)
31+
logger.info(f"SMS sent successfully: {message.sid}")
32+
except TwilioRestException as e:
33+
logger.error(f"Failed to send SMS: {e}")

server/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ watchdog==6.0.0
5050
wcwidth==0.2.13
5151
Werkzeug==3.1.3
5252
wheel==0.45.1
53-
wsproto==1.2.0
53+
wsproto==1.2.0
54+
load-dotenv==0.1.0

setup.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ EOF
143143
echo "ENABLE_DISTRIBUTED=false" >> .env
144144
fi
145145

146+
# Optional Twilio configuration
147+
if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_AUTH_TOKEN" ] && [ -n "$TWILIO_PHONE_NUMBER" ] && [ -n "$ALERT_RECIPIENT_PHONE" ]; then
148+
cat >> .env << EOF
149+
TWILIO_ACCOUNT_SID=$TWILIO_ACCOUNT_SID
150+
TWILIO_AUTH_TOKEN=$TWILIO_AUTH_TOKEN
151+
TWILIO_PHONE_NUMBER=$TWILIO_PHONE_NUMBER
152+
ALERT_RECIPIENT_PHONE=$ALERT_RECIPIENT_PHONE
153+
EOF
154+
fi
155+
146156
# Start the containers
147157
if [ "$ENV" == "production" ]; then
148158
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
@@ -177,6 +187,16 @@ EOF
177187
else
178188
echo "ENABLE_DISTRIBUTED=false" >> .env
179189
fi
190+
191+
# Optional Twilio configuration
192+
if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_AUTH_TOKEN" ] && [ -n "$TWILIO_PHONE_NUMBER" ] && [ -n "$ALERT_RECIPIENT_PHONE" ]; then
193+
cat >> .env << EOF
194+
TWILIO_ACCOUNT_SID=$TWILIO_ACCOUNT_SID
195+
TWILIO_AUTH_TOKEN=$TWILIO_AUTH_TOKEN
196+
TWILIO_PHONE_NUMBER=$TWILIO_PHONE_NUMBER
197+
ALERT_RECIPIENT_PHONE=$ALERT_RECIPIENT_PHONE
198+
EOF
199+
fi
180200

181201
echo "Local setup complete."
182202
echo "To start the backend server: cd server && python nanocas.py"

0 commit comments

Comments
 (0)