243 lines
15 KiB
Plaintext
243 lines
15 KiB
Plaintext
<!-- ===================== HERO ===================== -->
|
||
<section class="relative px-5 pt-20 pb-24 sm:px-8">
|
||
<div class="mx-auto max-w-5xl text-center">
|
||
<!-- Badge -->
|
||
<div class="fade-up inline-flex items-center gap-2 rounded-full glass px-4 py-1.5 text-xs">
|
||
<span class="relative flex h-2 w-2">
|
||
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-400 opacity-75"></span>
|
||
<span class="relative inline-flex h-2 w-2 rounded-full bg-sky-400"></span>
|
||
</span>
|
||
<span class="font-mono-tech uppercase tracking-[0.25em] text-slate-300">SMS Gateway · API v1</span>
|
||
</div>
|
||
|
||
<!-- Beacon logo -->
|
||
<div class="fade-up d-1 relative mx-auto mt-10 h-24 w-24 flex items-center justify-center">
|
||
<span class="beacon-ring absolute inset-0 rounded-full border border-sky-400/40"></span>
|
||
<span class="beacon-ring delay-1 absolute inset-0 rounded-full border border-sky-400/30"></span>
|
||
<span class="beacon-ring delay-2 absolute inset-0 rounded-full border border-sky-400/20"></span>
|
||
<div class="relative flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-400 to-sky-600 shadow-xl shadow-sky-500/40">
|
||
<i class="fas fa-sms text-3xl text-slate-950"></i>
|
||
</div>
|
||
</div>
|
||
|
||
<h1 class="fade-up d-2 font-display mt-8 text-5xl font-extrabold tracking-tight text-white sm:text-7xl">
|
||
Send SMS through your <span class="gradient-text">Android devices</span>
|
||
</h1>
|
||
|
||
<p class="fade-up d-3 mx-auto mt-6 max-w-2xl text-lg text-slate-400 sm:text-xl">
|
||
A production-grade REST & WebSocket API that turns any Android phone into a
|
||
programmable SMS gateway. Send messages, generate OTPs, receive inbound texts,
|
||
and orchestrate fleets of devices in real time.
|
||
</p>
|
||
|
||
<div class="fade-up d-4 mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||
<%= link_to docs_path, class: "btn-accent inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-950" do %>
|
||
<i class="fas fa-book-open"></i> Explore the API
|
||
<% end %>
|
||
<%= link_to admin_login_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-200" do %>
|
||
<i class="fas fa-gauge-high"></i> Admin Console
|
||
<% end %>
|
||
</div>
|
||
|
||
<!-- Base URL chip -->
|
||
<div class="fade-up d-5 mx-auto mt-12 inline-flex items-center gap-3 rounded-xl glass px-5 py-3">
|
||
<span class="font-mono-tech text-[11px] uppercase tracking-wider text-slate-500">Base URL</span>
|
||
<code class="font-mono-tech text-sm text-sky-300">https://<your-host>/api/v1</code>
|
||
<button data-copy="https://your-host/api/v1" class="copy-btn text-slate-500 hover:text-sky-400" aria-label="Copy base URL">
|
||
<i class="far fa-copy"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== STAT STRIP ===================== -->
|
||
<section class="relative px-5 sm:px-8">
|
||
<div class="mx-auto max-w-5xl">
|
||
<div class="grid grid-cols-2 gap-4 rounded-2xl glass px-6 py-6 sm:grid-cols-4">
|
||
<% stats = [
|
||
{ icon: "fa-bolt", value: "< 200ms", label: "API latency" },
|
||
{ icon: "fa-infinity", value: "Unlimited", label: "Gateways" },
|
||
{ icon: "fa-shield-halved", value: "SHA-256", label: "Key hashing" },
|
||
{ icon: "fa-rotate", value: "3× retry", label: "Auto backoff" }
|
||
] %>
|
||
<% stats.each do |s| %>
|
||
<div class="flex flex-col items-center text-center">
|
||
<i class="fas <%= s[:icon] %> text-sky-400"></i>
|
||
<span class="mt-2 font-display text-xl font-bold text-white"><%= s[:value] %></span>
|
||
<span class="font-mono-tech text-[10px] uppercase tracking-[0.2em] text-slate-500"><%= s[:label] %></span>
|
||
</div>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== FEATURES ===================== -->
|
||
<section class="relative px-5 py-24 sm:px-8">
|
||
<div class="mx-auto max-w-6xl">
|
||
<div class="mx-auto max-w-2xl text-center">
|
||
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Capabilities</p>
|
||
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Everything you need to route SMS at scale</h2>
|
||
<p class="mt-4 text-slate-400">From a single device to a distributed fleet — message queuing, delivery tracking, and OTP workflows are built in.</p>
|
||
</div>
|
||
|
||
<div class="mt-14 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||
<% features = [
|
||
{ icon: "fa-paper-plane", color: "from-sky-400 to-sky-600", title: "Send SMS", desc: "Queue outbound messages and let the gateway fleet deliver them. Automatic retries with exponential backoff." },
|
||
{ icon: "fa-arrow-down", color: "from-emerald-400 to-emerald-600", title: "Receive SMS", desc: "Inbound messages land in your inbox instantly and fire webhooks so your app reacts in real time." },
|
||
{ icon: "fa-shield-halved", color: "from-violet-400 to-violet-600", title: "OTP Generation", desc: "Six-digit codes with 5-minute expiry, 3-attempt limits, and 3-per-hour rate caps per phone number." },
|
||
{ icon: "fa-plug", color: "from-amber-400 to-orange-600", title: "Webhooks", desc: "HMAC-signed event payloads for sms_received, sms_sent and sms_failed with configurable retries." },
|
||
{ icon: "fa-tower-broadcast", color: "from-pink-400 to-rose-600", title: "Realtime WebSocket", desc: "Bidirectional Action Cable channel keeps every gateway in sync — heartbeats, delivery reports, and commands." },
|
||
{ icon: "fa-mobile-screen", color: "from-blue-400 to-indigo-600", title: "Gateway Fleet", desc: "Register unlimited Android devices. Priority-based routing, health checks, and live status monitoring." }
|
||
] %>
|
||
<% features.each_with_index do |f, i| %>
|
||
<div class="fade-up d-<%= (i % 3) + 1 %> group rounded-2xl glass p-6 transition-all duration-300 hover:-translate-y-1 hover:border-sky-400/30">
|
||
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br <%= f[:color] %> shadow-lg">
|
||
<i class="fas <%= f[:icon] %> text-lg text-slate-950"></i>
|
||
</div>
|
||
<h3 class="font-display mt-5 text-xl font-bold text-white"><%= f[:title] %></h3>
|
||
<p class="mt-2 text-sm leading-relaxed text-slate-400"><%= f[:desc] %></p>
|
||
</div>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== ARCHITECTURE ===================== -->
|
||
<section class="relative px-5 py-24 sm:px-8">
|
||
<div class="mx-auto max-w-6xl">
|
||
<div class="mx-auto max-w-2xl text-center">
|
||
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Architecture</p>
|
||
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">How messages flow</h2>
|
||
<p class="mt-4 text-slate-400">A clean, asynchronous pipeline keeps the API fast and delivery resilient.</p>
|
||
</div>
|
||
|
||
<div class="mt-14 grid items-stretch gap-4 lg:grid-cols-5">
|
||
<% steps = [
|
||
{ n: "01", icon: "fa-code", title: "Client calls API", desc: "POST /api/v1/sms/send with a Bearer API key. Phone numbers are validated with Phonelib." },
|
||
{ n: "02", icon: "fa-database", title: "Message queued", desc: "SmsMessage is persisted and SendSmsJob is enqueued via Sidekiq. The API returns instantly with a message_id." },
|
||
{ n: "03", icon: "fa-route", title: "Gateway selected", desc: "SendSmsJob picks the highest-priority online, active gateway and broadcasts over Action Cable." },
|
||
{ n: "04", icon: "fa-mobile-screen-button", title: "Android delivers", desc: "The gateway device sends the SMS via its native radio and reports back a delivery status." },
|
||
{ n: "05", icon: "fa-circle-check", title: "Status & webhooks", desc: "Delivery/failed status is recorded; webhooks fire for subscribed events. Failed messages auto-retry up to 3×." }
|
||
] %>
|
||
<% steps.each do |s| %>
|
||
<div class="relative rounded-2xl glass p-6">
|
||
<span class="font-mono-tech text-xs text-sky-400/70"><%= s[:n] %></span>
|
||
<i class="fas <%= s[:icon] %> mt-3 text-2xl text-sky-400"></i>
|
||
<h3 class="font-display mt-3 text-base font-bold text-white"><%= s[:title] %></h3>
|
||
<p class="mt-2 text-xs leading-relaxed text-slate-400"><%= s[:desc] %></p>
|
||
</div>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== QUICK START ===================== -->
|
||
<section class="relative px-5 py-24 sm:px-8">
|
||
<div class="mx-auto max-w-5xl">
|
||
<div class="text-center">
|
||
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Quick Start</p>
|
||
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Send your first message</h2>
|
||
</div>
|
||
|
||
<div class="mt-12 grid gap-6 lg:grid-cols-2">
|
||
<!-- Step 1 -->
|
||
<div class="rounded-2xl glass p-6">
|
||
<div class="flex items-center gap-3">
|
||
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">1</span>
|
||
<h3 class="font-display text-lg font-bold text-white">Register a gateway device</h3>
|
||
</div>
|
||
<p class="mt-3 text-sm text-slate-400">No auth required — receive a gateway API key back.</p>
|
||
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
|
||
<span class="tok-com"># Register your Android device</span><br>
|
||
<span class="tok-key">curl</span> -X POST https://your-host/api/v1/gateway/register \<br>
|
||
-H <span class="tok-str">"Content-Type: application/json"</span> \<br>
|
||
-d <span class="tok-str">'{"device_id":"pixel-001","name":"Office Phone"}'</span>
|
||
</div>
|
||
<div class="mt-3 flex items-center gap-2">
|
||
<button data-copy='curl -X POST https://your-host/api/v1/gateway/register -H "Content-Type: application/json" -d "{\"device_id\":\"pixel-001\",\"name\":\"Office Phone\"}"' class="copy-btn text-xs text-slate-500 hover:text-sky-400"><i class="far fa-copy"></i> Copy</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 2 -->
|
||
<div class="rounded-2xl glass p-6">
|
||
<div class="flex items-center gap-3">
|
||
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">2</span>
|
||
<h3 class="font-display text-lg font-bold text-white">Connect via WebSocket</h3>
|
||
</div>
|
||
<p class="mt-3 text-sm text-slate-400">Keep the device online and ready to receive commands.</p>
|
||
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
|
||
<span class="tok-com"># wscat</span><br>
|
||
<span class="tok-key">wscat</span> -c <span class="tok-str">"ws://your-host:3000/cable?api_key=gw_live_..."</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 3 -->
|
||
<div class="rounded-2xl glass p-6 lg:col-span-2">
|
||
<div class="flex items-center gap-3">
|
||
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">3</span>
|
||
<h3 class="font-display text-lg font-bold text-white">Send an SMS</h3>
|
||
</div>
|
||
<p class="mt-3 text-sm text-slate-400">Use a client API key (api_live_…) in the Authorization header.</p>
|
||
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
|
||
<span class="tok-key">curl</span> -X POST https://your-host/api/v1/sms/send \<br>
|
||
-H <span class="tok-str">"Authorization: Bearer api_live_..."</span> \<br>
|
||
-H <span class="tok-str">"Content-Type: application/json"</span> \<br>
|
||
-d <span class="tok-str">'{"to":"+14155551234","message":"Hello from MySMSAPio!"}'</span>
|
||
</div>
|
||
<div class="mt-3 flex items-center gap-2">
|
||
<button data-copy='curl -X POST https://your-host/api/v1/sms/send -H "Authorization: Bearer api_live_..." -H "Content-Type: application/json" -d "{\"to\":\"+14155551234\",\"message\":\"Hello from MySMSAPio!\"}"' class="copy-btn text-xs text-slate-500 hover:text-sky-400"><i class="far fa-copy"></i> Copy</button>
|
||
</div>
|
||
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
|
||
<span class="tok-com"># → 202 Accepted</span><br>
|
||
{<br>
|
||
<span class="tok-key">"success"</span>: <span class="tok-bool">true</span>,<br>
|
||
<span class="tok-key">"message_id"</span>: <span class="tok-str">"msg_3f8a9c1b2e7d4f60"</span>,<br>
|
||
<span class="tok-key">"status"</span>: <span class="tok-str">"queued"</span><br>
|
||
}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-10 text-center">
|
||
<%= link_to docs_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-6 py-3 text-sm font-semibold text-slate-200" do %>
|
||
<i class="fas fa-arrow-right-long"></i> Read the full API reference
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== TECH STACK ===================== -->
|
||
<section class="relative px-5 py-24 sm:px-8">
|
||
<div class="mx-auto max-w-5xl">
|
||
<div class="text-center">
|
||
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Built on a modern stack</p>
|
||
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Production-ready by default</h2>
|
||
</div>
|
||
<div class="mt-12 flex flex-wrap items-center justify-center gap-3">
|
||
<% stack = ["Rails 8.0", "Ruby 3.4", "PostgreSQL", "Redis 7", "Sidekiq 7", "Action Cable", "Puma + Thruster", "Docker / Kamal", "Tailwind CSS", "Phonelib", "HTTParty", "ROTP"] %>
|
||
<% stack.each do |tech| %>
|
||
<span class="rounded-full glass px-5 py-2 font-mono-tech text-xs text-slate-300"><%= tech %></span>
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===================== CTA ===================== -->
|
||
<section class="relative px-5 py-24 sm:px-8">
|
||
<div class="mx-auto max-w-4xl">
|
||
<div class="relative overflow-hidden rounded-3xl glass-strong px-8 py-16 text-center sm:px-16">
|
||
<div class="pointer-events-none absolute -top-24 left-1/2 h-64 w-64 -translate-x-1/2 rounded-full bg-sky-500/20 blur-3xl"></div>
|
||
<h2 class="font-display relative text-4xl font-bold text-white sm:text-5xl">Ready to send your first SMS?</h2>
|
||
<p class="relative mx-auto mt-4 max-w-xl text-slate-400">Dive into the complete API reference or jump straight into the admin console to manage your gateways.</p>
|
||
<div class="relative mt-8 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||
<%= link_to docs_path, class: "btn-accent inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-950" do %>
|
||
<i class="fas fa-book"></i> API Documentation
|
||
<% end %>
|
||
<%= link_to admin_login_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-200" do %>
|
||
<i class="fas fa-gauge-high"></i> Open Admin Console
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|