<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Harpreet Singh</title>
    <description>The latest articles on Forem by Harpreet Singh (@harpreet_singh_68ce0b24d8).</description>
    <link>https://forem.com/harpreet_singh_68ce0b24d8</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3279798%2F5f355f39-3244-4b1a-8059-93dd1ae3fa12.jpg</url>
      <title>Forem: Harpreet Singh</title>
      <link>https://forem.com/harpreet_singh_68ce0b24d8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/harpreet_singh_68ce0b24d8"/>
    <language>en</language>
    <item>
      <title>📲Build Your Own SMS OTP Sender Using Termux + Python + Port Forwarding</title>
      <dc:creator>Harpreet Singh</dc:creator>
      <pubDate>Fri, 20 Jun 2025 21:48:32 +0000</pubDate>
      <link>https://forem.com/harpreet_singh_68ce0b24d8/build-your-own-sms-otp-sender-using-termux-python-port-forwarding-3kpn</link>
      <guid>https://forem.com/harpreet_singh_68ce0b24d8/build-your-own-sms-otp-sender-using-termux-python-port-forwarding-3kpn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Ever wondered how OTP systems work?&lt;/strong&gt; In this blog, we’ll build a simple SMS OTP Sender using your &lt;strong&gt;Android phone&lt;/strong&gt;, &lt;strong&gt;Termux&lt;/strong&gt;, and a little bit of &lt;strong&gt;Python&lt;/strong&gt; magic. It’s a fun way to learn about messaging automation, APIs, and port forwarding — especially if you're a beginner in backend or ethical hacking!&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Tools &amp;amp; Technologies Used
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Termux (Android) – Linux terminal emulator for Android.&lt;/li&gt;
&lt;li&gt;Termux: API – Provides access to Android’s native APIs like SMS.&lt;/li&gt;
&lt;li&gt;Python – To build a simple backend script.&lt;/li&gt;
&lt;li&gt;Flask – Lightweight Python web framework.&lt;/li&gt;
&lt;li&gt;Cloudflare Tunnel / Ngrok – To expose the local server to the internet.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📦 Step 1: Setup Termux on Android
&lt;/h2&gt;

&lt;p&gt;Install Termux from F-Droid (not Play Store):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pkg update &amp;amp;&amp;amp; pkg upgrade
pkg install python
pkg install termux-api
pip install flask

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also install Termux API app from F-Droid (important).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Write the SMS Sender in Python
&lt;/h2&gt;

&lt;p&gt;Create a file called sms_sender.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import os
from http.server import BaseHTTPRequestHandler, HTTPServer

class RequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        if self.path == "/send-sms":
            content_length = int(self.headers["Content-Length"])
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data)

            phone = data.get("phone")
            otp = data.get("otp")

            if phone and otp:
                command = f'termux-sms-send -n {phone} "Your OTP is {otp}"'
                print(f"Executing: {command}")  # Debugging statement

                # Use os.system to execute the command
                result = os.system(command)

                # Check the result code
                if result == 0:
                    print("✅ SMS sent successfully!")
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(json.dumps({"message": "OTP Sent"}).encode())
                else:
                    print("❌ Failed to send SMS! Error code:", result)
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(json.dumps({"error": "Failed to send SMS"}).encode())
            else:
                self.send_response(400)
                self.end_headers()
                self.wfile.write(json.dumps({"error": "Invalid data"}).encode())

server_address = ("", 8080)  # Running server on port 8080
httpd = HTTPServer(server_address, RequestHandler)
print("📡 Termux SMS Server running on port 8080...")
httpd.serve_forever()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌐 Step 3: Port Forward with Cloudflare Tunnel
&lt;/h2&gt;

&lt;p&gt;When you're building a local project, your services usually run on your machine and are only accessible from your own device. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your frontend (React, etc.) runs on localhost:3000&lt;/li&gt;
&lt;li&gt;Your backend server runs on localhost:8080&lt;/li&gt;
&lt;li&gt;Your database runs on localhost:5432&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here’s the problem:&lt;br&gt;
These &lt;strong&gt;localhost&lt;/strong&gt; ports are not accessible from outside your machine.&lt;/p&gt;

&lt;p&gt;So, how do you access your local app from another device? Or share it with a team member or webhook service?&lt;/p&gt;

&lt;p&gt;You have &lt;strong&gt;two options&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Buy a &lt;strong&gt;domain + server&lt;/strong&gt;, deploy your services, and make them public.&lt;/p&gt;

&lt;p&gt;Or — use &lt;strong&gt;port forwarding&lt;/strong&gt; with tunneling services like &lt;strong&gt;Cloudflare Tunnel or ngrok&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔁 What is Port Forwarding?
&lt;/h3&gt;

&lt;p&gt;Port forwarding is a method to expose a specific port (running locally) to the internet, by tunneling it through a public URL.&lt;/p&gt;
&lt;h3&gt;
  
  
  👉Example: Cloudflare Tunnel for Port Forwarding
&lt;/h3&gt;

&lt;p&gt;Let’s say we’re working on a full-stack app that runs locally like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3000&lt;/strong&gt; → Frontend (React app)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8080&lt;/strong&gt; → Backend Server (API)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5432&lt;/strong&gt; → PostgreSQL Database&lt;/p&gt;

&lt;p&gt;Here's a visual representation of our local setup:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frydcrvxy20eeqj20elsl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frydcrvxy20eeqj20elsl.png" alt="exposing localhost using tunnel" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the image:&lt;/p&gt;

&lt;p&gt;All services are running locally.&lt;/p&gt;

&lt;p&gt;We use a &lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt; to expose these local ports to the outside world.&lt;/p&gt;

&lt;p&gt;This tunnel creates a &lt;strong&gt;public URL&lt;/strong&gt; that anyone can access — just like a real deployed app.&lt;/p&gt;
&lt;h3&gt;
  
  
  To forward your local Flask server (running on port 8080), use:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudflared tunnel --url http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  🧪 Step 4: Test the SMS API
&lt;/h2&gt;

&lt;p&gt;Here once the Cloudflare Tunnel was set up and pointing to to my Termux Flask server, we need a way to trigger rigger the OTP sending from my backend. So I created an API route that would generate an OTP, save it in the database for short duration, and send a request to my Termux SMS server to deliver the OTP to the user’s phone.&lt;/p&gt;
&lt;h3&gt;
  
  
  Here's how I tested it:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;📡 Make a POST request to the Termux server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I exposed the Termux Flask server (running on my phone) using Cloudflare Tunnel. Then, I hit this public URL with a simple POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://yourname.trycloudflare.com/send-sms
Content-Type: application/json

{
  "number": "9876543210",
  "message": "Your OTP is 6789"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You can do this using Postman, or directly from terminal with curl:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST https://yourname.trycloudflare.com/send-sms \
-H "Content-Type: application/json" \
-d '{"number": "9876543210", "message": "Your OTP is 6789"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;And boom 💥 — the message is sent directly from my Android phone using Termux’s native termux-sms-send command.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This worked great for me during testing — no need for third-party SMS providers or paid APIs. I used this method to &lt;strong&gt;automate OTP delivery&lt;/strong&gt; in my full-stack app.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 TL;DR
&lt;/h2&gt;

&lt;p&gt;In this blog, I built a DIY SMS OTP sender using just:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Android phone running Termux&lt;/li&gt;
&lt;li&gt;A Python + Flask server to send SMS via termux-sms-send&lt;/li&gt;
&lt;li&gt;A Cloudflare Tunnel to expose the local API publicly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also connected this setup with a backend (Node.js + MongoDB) that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates an OTP&lt;/li&gt;
&lt;li&gt;Stores it temporarily&lt;/li&gt;
&lt;li&gt;Verifies it securely when submitted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project avoids third-party SMS services, is perfect for local development/testing, and helps you understand port forwarding, automation, and full-stack OTP systems using open tools.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>development</category>
      <category>python</category>
      <category>termux</category>
    </item>
  </channel>
</rss>
