-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from rishabkumar7/rk-relay-sms
added python code for send-and-receive-sms-anonymously-python
- Loading branch information
Showing
5 changed files
with
376 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,4 @@ | ||
TWILIO_ACCOUNT_SID="<YOUR_TWILIO_ACCOUNT_SID>" | ||
TWILIO_AUTH_TOKEN="<YOUR_TWILIO_AUTH_TOKEN>" | ||
MY_PHONE_NUMBER="<YOUR_PHONE_NUMBER>" | ||
TWILIO_PHONE_NUMBER="<YOUR_TWILIO_PHONE_NUMBER>" |
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,164 @@ | ||
# Python .gitignore file from - https://github.com/github/gitignore/blob/main/Python.gitignore | ||
|
||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
*.py,cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
cover/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
.pybuilder/ | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
# For a library or package, you might want to ignore these files since the code is | ||
# intended to run in multiple environments; otherwise, check them in: | ||
# .python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# poetry | ||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. | ||
# This is especially recommended for binary packages to ensure reproducibility, and is more | ||
# commonly ignored for libraries. | ||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control | ||
#poetry.lock | ||
|
||
# pdm | ||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. | ||
#pdm.lock | ||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it | ||
# in version control. | ||
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control | ||
.pdm.toml | ||
.pdm-python | ||
.pdm-build/ | ||
|
||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm | ||
__pypackages__/ | ||
|
||
# Celery stuff | ||
celerybeat-schedule | ||
celerybeat.pid | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ | ||
|
||
# pytype static type analyzer | ||
.pytype/ | ||
|
||
# Cython debug symbols | ||
cython_debug/ | ||
|
||
# PyCharm | ||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can | ||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore | ||
# and can be added to the global gitignore or merged into this file. For a more nuclear | ||
# option (not recommended) you can uncomment the following to ignore the entire idea folder. | ||
#.idea/ |
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 |
---|---|---|
@@ -1 +1,84 @@ | ||
# send-and-receive-sms-anonymously-python | ||
# Send and Receive SMS Anonymously Python | ||
|
||
## Description | ||
|
||
This Flask application serves as an SMS relay using Twilio. It allows you to use a Twilio phone number as a proxy for sending and receiving SMS messages, effectively masking your personal phone number from the public. | ||
When the Twilio phone number associated with this application receives a message: | ||
|
||
- If the message is from your personal number, it forwards the message to a specified recipient. | ||
- If the message is from any other number, it relays the message to your personal number. | ||
|
||
## Table of Contents | ||
|
||
1. Installation | ||
2. Configuration | ||
3. Usage | ||
4. License | ||
|
||
## Installation | ||
|
||
Clone this repository: | ||
|
||
```sh | ||
git clone https://github.com/twilio-samples/send-and-receive-sms-anonymously-python.git | ||
|
||
cd twilio-sms-relay | ||
``` | ||
|
||
Create and activate a virtual environment: | ||
|
||
```sh | ||
python -m venv venv | ||
source venv/bin/activate # On Windows use `venv\Scripts\activate` | ||
``` | ||
|
||
Install the required packages: | ||
|
||
```sh | ||
pip install -r requirements.txt | ||
``` | ||
|
||
## Configuration | ||
|
||
You will need a [Twilio Phone number](https://help.twilio.com/articles/223135247) and your Twilio Account SID and AUTH Token. | ||
Set up the following environment variables, copy the `.env.example` and create a new `.env` file: | ||
|
||
``` | ||
TWILIO_ACCOUNT_SID="your_account_sid" | ||
TWILIO_AUTH_TOKEN="your_auth_token" | ||
MY_PHONE_NUMBER="your_personal_number" | ||
TWILIO_PHONE_NUMBER="your_twilio_number" | ||
``` | ||
|
||
## Usage | ||
|
||
Run the Flask application: | ||
|
||
```sh | ||
python app.py | ||
``` | ||
|
||
The application will start on `http://127.0.0.1:5000/`. | ||
|
||
Install ngrok: https://ngrok.com/download | ||
|
||
In another terminal, start ngrok: | ||
|
||
```sh | ||
ngrok http 5000 | ||
``` | ||
|
||
Use the ngrok URL with `/sms` as the endpoint as your Twilio webhook URL, for example `https://xxxxxx.ngrok.app/sms`. | ||
|
||
To send a message through the relay, text your Twilio number from your personal number with the format: | ||
|
||
``` | ||
+1XXXXXXXXXX: Your message here | ||
``` | ||
|
||
Replace `+1XXXXXXXXXX` with the recipient's phone number. | ||
Any messages sent to your Twilio number will be forwarded to your personal number. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License - see the [LICENSE](/LICENSE) file for details. |
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,101 @@ | ||
""" | ||
Twilio SMS Relay Flask Application | ||
Description: This Flask application acts as an SMS relay using Twilio. | ||
When the associated Twilio phone number receives a message, it either | ||
forwards the message to a specified number or relays it to your personal number. | ||
Contents: | ||
1. Imports and Setup | ||
2. Environment Variables | ||
3. Main Handler (sms_reply function) | ||
4. Application Entry Point | ||
""" | ||
|
||
# 1. Imports and Setup | ||
# | ||
# Here we import the necessary libraries and initialize our Flask application. | ||
# We also set up the Twilio client for making API calls. | ||
|
||
from flask import Flask, request | ||
from twilio.twiml.messaging_response import MessagingResponse | ||
from twilio.rest import Client | ||
import os | ||
|
||
from dotenv import load_dotenv | ||
load_dotenv() | ||
|
||
|
||
app = Flask(__name__) | ||
|
||
|
||
# 2. Environment Variables | ||
# | ||
# We load the necessary credentials and phone numbers from environment variables. | ||
# This keeps sensitive information out of the code and allows for easier configuration | ||
# across different environments. | ||
|
||
TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID') | ||
TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN') | ||
MY_PHONE_NUMBER = os.getenv('MY_PHONE_NUMBER') | ||
TWILIO_PHONE_NUMBER = os.getenv('TWILIO_PHONE_NUMBER') | ||
|
||
# Initialize Twilio client | ||
client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) | ||
|
||
# 3. Main Handler (sms_reply function) | ||
# | ||
# This is the main entry point of our application. It handles incoming SMS messages | ||
# and determines how to process them based on the sender's number. | ||
# If the message is from your personal number, it parses the message to send to another recipient. | ||
# If the message is from any other number, it forwards the message to your personal number. | ||
|
||
@app.route("/sms", methods=['POST']) | ||
def sms_reply(): | ||
# Extract incoming message details | ||
from_number = request.form['From'] | ||
to_number = request.form['To'] | ||
body = request.form['Body'] | ||
|
||
# Initialize TwiML response | ||
resp = MessagingResponse() | ||
|
||
if from_number == MY_PHONE_NUMBER: | ||
# Message is from your personal number | ||
separator_position = body.find(':') | ||
|
||
if separator_position < 1: | ||
# If the message format is incorrect, send an instructional message back | ||
resp.message('You need to specify a recipient number and a ":" before the message. For example, "+12223334444: message".') | ||
else: | ||
# Parse the recipient number and message body | ||
recipient_number = body[:separator_position].strip() | ||
message_body = body[separator_position + 1:].strip() | ||
|
||
try: | ||
# Attempt to send the message using Twilio client | ||
client.messages.create( | ||
to=recipient_number, | ||
from_=to_number, | ||
body=message_body | ||
) | ||
except Exception as e: | ||
# If there's an error (e.g., invalid phone number), send an error message back | ||
resp.message('There was an issue with the phone number you entered; please verify it is correct and try again.') | ||
else: | ||
# Message is from another number, forward it to your personal number | ||
client.messages.create( | ||
to=MY_PHONE_NUMBER, | ||
from_=TWILIO_PHONE_NUMBER, | ||
body=f"{from_number}: {body}" | ||
) | ||
|
||
# Return the TwiML response | ||
return str(resp) | ||
|
||
# 4. Application Entry Point | ||
# | ||
# This section runs the Flask application when the script is executed directly. | ||
# The debug mode is set to True, which is useful for development but should be set to False in production. | ||
if __name__ == "__main__": | ||
app.run(debug=True) |
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,23 @@ | ||
aiohappyeyeballs==2.4.0 | ||
aiohttp==3.10.5 | ||
aiohttp-retry==2.8.3 | ||
aiosignal==1.3.1 | ||
attrs==24.2.0 | ||
blinker==1.8.2 | ||
certifi==2024.8.30 | ||
charset-normalizer==3.3.2 | ||
click==8.1.7 | ||
Flask==3.0.3 | ||
frozenlist==1.4.1 | ||
idna==3.8 | ||
itsdangerous==2.2.0 | ||
Jinja2==3.1.4 | ||
MarkupSafe==2.1.5 | ||
multidict==6.0.5 | ||
PyJWT==2.9.0 | ||
python-dotenv==1.0.1 | ||
requests==2.32.3 | ||
twilio==9.2.4 | ||
urllib3==2.2.2 | ||
Werkzeug==3.0.4 | ||
yarl==1.9.7 |