completed SMS gateway project

This commit is contained in:
Min Zeya Phyo
2025-10-22 17:22:17 +08:00
commit c883fa7128
190 changed files with 16294 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
module Api
module V1
module Gateway
class BaseController < ApplicationController
include ApiAuthenticatable
include RateLimitable
end
end
end
end

View File

@@ -0,0 +1,30 @@
module Api
module V1
module Gateway
class HeartbeatsController < BaseController
def create
current_gateway.heartbeat!
# Update metadata with device info
metadata = {
battery_level: params[:battery_level],
signal_strength: params[:signal_strength],
messages_in_queue: params[:messages_in_queue]
}.compact
current_gateway.update(metadata: metadata) if metadata.any?
# Get count of pending messages for this gateway
pending_count = SmsMessage.pending
.where(gateway_id: [nil, current_gateway.id])
.count
render json: {
success: true,
pending_messages: pending_count
}
end
end
end
end
end

View File

@@ -0,0 +1,53 @@
module Api
module V1
module Gateway
class RegistrationsController < ApplicationController
skip_before_action :authenticate_api_key!, only: [:create]
def create
device_id = params.require(:device_id)
name = params[:name] || "Gateway #{device_id[0..7]}"
# Check if gateway already exists
gateway = ::Gateway.find_by(device_id: device_id)
if gateway
render json: {
success: false,
error: "Gateway already registered"
}, status: :conflict
return
end
# Create new gateway
gateway = ::Gateway.new(
device_id: device_id,
name: name,
status: "offline"
)
raw_key = gateway.generate_api_key!
render json: {
success: true,
api_key: raw_key,
device_id: gateway.device_id,
websocket_url: websocket_url
}, status: :created
rescue ActionController::ParameterMissing => e
render json: { error: e.message }, status: :bad_request
end
private
def websocket_url
if Rails.env.production?
"wss://#{request.host}/cable"
else
"ws://#{request.host}:#{request.port}/cable"
end
end
end
end
end
end

View File

@@ -0,0 +1,61 @@
module Api
module V1
module Gateway
class SmsController < BaseController
# POST /api/v1/gateway/sms/received
def received
sender = params.require(:sender)
message = params.require(:message)
timestamp = params[:timestamp] || Time.current
# Create inbound SMS message
sms = SmsMessage.create!(
gateway: current_gateway,
direction: "inbound",
phone_number: sender,
message_body: message,
status: "delivered",
delivered_at: timestamp
)
# Increment received counter
current_gateway.increment_received_count!
# Process inbound message asynchronously
ProcessInboundSmsJob.perform_later(sms.id)
render json: {
success: true,
message_id: sms.message_id
}
rescue ActionController::ParameterMissing => e
render json: { error: e.message }, status: :bad_request
end
# POST /api/v1/gateway/sms/status
def status
message_id = params.require(:message_id)
status = params.require(:status)
error_message = params[:error_message]
sms = SmsMessage.find_by!(message_id: message_id)
case status
when "delivered"
sms.mark_delivered!
when "failed"
sms.mark_failed!(error_message)
# Retry if possible
RetryFailedSmsJob.perform_later(sms.id) if sms.can_retry?
when "sent"
sms.update!(status: "sent", sent_at: Time.current)
end
render json: { success: true }
rescue ActionController::ParameterMissing => e
render json: { error: e.message }, status: :bad_request
end
end
end
end
end