Introduction
Back in 2018, I started an "IoT Weekend" project using Heroku and CloudMQTT. Fast forward to 2026, the landscape has changed significantly. We have moved away from permanent virtual servers toward more robust serverless options, better security standards, and more efficient hardware.
In this updated guide, I’ll show you how to build a smart-home controller using the LINE Messaging API and MQTT, modernized for today’s developer workflow.
The 2026 Architecture
The flow remains elegant but is now more scalable and secure:
- User triggers a command via a LINE Rich Menu.
- LINE Platform hits a Serverless Webhook (Vercel/Next.js).
- Webhook publishes a secure message to a Cloud MQTT Broker (HiveMQ/EMQX).
- IoT Device (ESP32-S3) receives the command via a TLS-secured connection and toggles the hardware.
Key Tech Stack
- Hardware: ESP32-S3 (with built-in hardware security)
- Protocol: MQTT 5.0 (The modern standard for low-latency IoT)
- Backend: Next.js / TypeScript (deployed on Vercel)
- Broker: HiveMQ Cloud (Serverless MQTT)
- API: LINE Messaging API v2
Why MQTT 5.0 in 2026?
While REST APIs are great, MQTT 5.0 is the backbone of the "Matter" era. It offers:
- Binary Data handling: Highly efficient for tiny sensors.
- Shared Subscriptions: Better load balancing for multiple devices.
- Enhanced Auth: We now use TLS/SSL by default to ensure no one "sniffs" your home commands.
Preparation
- LINE Developers Account: To create your provider and channel.
- HiveMQ Cloud (Free Tier): Our modern MQTT broker.
- Vercel Account: For hosting our webhook without managing servers.
- Hardware: ESP32-S3, an LED, and a 220-ohm resistor.
Step 1: Setting up the Modern MQTT Broker
We’re skipping the old Heroku add-ons for a dedicated IoT SaaS.
- Go to HiveMQ Cloud.
- Create a Serverless Cluster (Free).
- Security First: Create a "Database User" in the HiveMQ console. This credential will be used by your ESP32 and Webhook.
- Note your Cluster URL (e.g.,
xxxxxx.s1.eu.hivemq.cloud).
Step 2: Deploying the Webhook (Serverless)
Instead of a long-running server, we use a TypeScript function. It wakes up, sends the MQTT command, and goes back to sleep—saving costs and resources.
// api/webhook.ts (Next.js / Vercel)
import mqtt from 'mqtt';
export default async function handler(req, res) {
const client = await mqtt.connectAsync('mqtts://YOUR_CLUSTER_URL', {
username: 'YOUR_USER',
password: 'YOUR_PASSWORD',
port: 8883 // Secure port
});
if (req.body.events[0].message.text === 'ON') {
await client.publishAsync('home/living-room/light', '1');
}
res.status(200).send('OK');
}
Step 3: Hardware Evolution (ESP32-S3)
In 2026, we no longer use unencrypted connections (Port 1883). Modern IoT hardware like the ESP32-S3 features hardware acceleration for encryption, allowing us to use TLS/SSL (Port 8883) with minimal impact on performance.
Secure Connection Code (Arduino IDE Compatible)
To run this in the Arduino IDE, make sure you have installed the ArduinoMqttClient library via the Library Manager. This code uses WiFiClientSecure to handle the modern MQTT 5.0 encrypted handshake.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoMqttClient.h>
// WiFi & HiveMQ Credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* broker = "YOUR_CLUSTER_URL.s1.eu.hivemq.cloud";
const char* mqttUser = "YOUR_DEVICE_USER";
const char* mqttPass = "YOUR_DEVICE_PASS";
WiFiClientSecure wifiClient;
MqttClient mqttClient(wifiClient);
// The LED pin - Pin 2 is common for built-in LEDs, adjust if using ESP32-S3 DevKit
const int ledPin = 2;
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// In 2026, we prioritize TLS 1.3
// For development, we can skip cert validation, but production should use setCACert()
wifiClient.setInsecure();
mqttClient.setId("ESP32_Line_Controller");
mqttClient.setUsernamePassword(mqttUser, mqttPass);
Serial.print("Attempting to connect to MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, 8883)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("Connected to HiveMQ!");
mqttClient.subscribe("home/living-room/light");
}
void loop() {
// Keep the connection alive and check for messages
mqttClient.poll();
// Listen for the '1' or '0' payload sent from your LINE Bot via Vercel
while (mqttClient.available()) {
char c = (char)mqttClient.read();
Serial.print("Message received: ");
Serial.println(c);
if (c == '1') {
digitalWrite(ledPin, HIGH);
} else if (c == '0') {
digitalWrite(ledPin, LOW);
}
}
}
Summary: 2018 vs. 2026 Standards
The transition from 2018 to 2026 represents a shift from "making it work" to "making it secure and scalable." Below is a comparison of how the tech stack has evolved over the years.
| Feature | 2018 Approach | 2026 Modern Standard |
|---|---|---|
| Hosting | Heroku (Monolithic) | Vercel / Cloudflare (Serverless) |
| MQTT Protocol | MQTT 3.1.1 (Insecure) | MQTT 5.0 (TLS/SSL Secured) |
| Language | Ruby / Sinatra | TypeScript / Node.js |
| Cloud Broker | CloudMQTT | HiveMQ / EMQX Cloud |
| Security | Basic Auth (Plaintext) | Token-based / TLS 1.3 Encryption |
Conclusion
The shift from 2018 to 2026 isn't just about different tools; it's about adopting a Security-First and Scalable mindset. By leveraging Serverless functions and TLS-secured MQTT, your IoT projects are now more responsive, cheaper to maintain, and significantly more secure against modern threats.
What's Next?
In Part 2, we will configure the LINE Rich Menu. This will allow you to control your home with a polished UI—tapping physical icons on your phone screen instead of typing commands—and we'll set up Vercel environment variables to keep your credentials safe.
Happy Coding! 🚀


Top comments (0)