module Admin class GatewaysController < BaseController def index @gateways = Gateway.order(created_at: :desc) end def new @gateway = Gateway.new end def create @gateway = Gateway.new( device_id: params[:gateway][:device_id], name: params[:gateway][:name], priority: params[:gateway][:priority] || 1, status: "offline" ) # Generate API key for the gateway raw_key = @gateway.generate_api_key! # Store in session to pass to show action session[:new_gateway_id] = @gateway.id session[:new_gateway_raw_key] = raw_key redirect_to admin_gateway_path(@gateway) rescue StandardError => e Rails.logger.error "Gateway creation failed: #{e.message}\n#{e.backtrace.join("\n")}" flash.now[:alert] = "Error creating gateway: #{e.message}" @gateway ||= Gateway.new render :new, status: :unprocessable_entity end def show @gateway = Gateway.find(params[:id]) # Check if this is a newly created gateway (from session) if session[:new_gateway_id] == @gateway.id && session[:new_gateway_raw_key].present? @raw_key = session[:new_gateway_raw_key] @is_new = true # Generate QR code with configuration data @qr_code_data = generate_qr_code_data(@raw_key) # Clear session data after retrieving session.delete(:new_gateway_id) session.delete(:new_gateway_raw_key) else @is_new = false @recent_messages = SmsMessage.where(gateway_id: @gateway.id).order(created_at: :desc).limit(20) end end private def generate_qr_code_data(api_key) require "rqrcode" # Determine the base URL and WebSocket URL base_url = request.base_url ws_url = request.base_url.sub(/^http/, "ws") + "/cable" # Create JSON configuration for the Android app config_data = { api_key: api_key, api_base_url: base_url, websocket_url: ws_url, version: "1.0" }.to_json # Generate QR code qr = RQRCode::QRCode.new(config_data, level: :h) # Return as SVG string qr.as_svg( offset: 0, color: "000", shape_rendering: "crispEdges", module_size: 4, standalone: true, use_path: true ) end def toggle @gateway = Gateway.find(params[:id]) @gateway.update!(active: !@gateway.active) redirect_to admin_gateways_path, notice: "Gateway #{@gateway.active? ? 'activated' : 'deactivated'}" rescue => e redirect_to admin_gateways_path, alert: "Error updating gateway: #{e.message}" end def test @gateway = Gateway.find(params[:id]) rescue ActiveRecord::RecordNotFound redirect_to admin_gateways_path, alert: "Gateway not found" end def check_connection @gateway = Gateway.find(params[:id]) # Check if gateway is online based on recent heartbeat if @gateway.online? render json: { status: "success", message: "Gateway is online", last_heartbeat: @gateway.last_heartbeat_at, time_ago: helpers.time_ago_in_words(@gateway.last_heartbeat_at) } else render json: { status: "error", message: "Gateway is offline", last_heartbeat: @gateway.last_heartbeat_at, time_ago: @gateway.last_heartbeat_at ? helpers.time_ago_in_words(@gateway.last_heartbeat_at) : "never" } end rescue StandardError => e render json: { status: "error", message: e.message }, status: :internal_server_error end def send_test_sms @gateway = Gateway.find(params[:id]) phone_number = params[:phone_number] message_body = params[:message_body] if phone_number.blank? || message_body.blank? render json: { status: "error", message: "Phone number and message are required" }, status: :unprocessable_entity return end # Create test SMS message sms = SmsMessage.create!( direction: "outbound", phone_number: phone_number, message_body: message_body, gateway: @gateway, metadata: { test: true, sent_from: "admin_interface" } ) render json: { status: "success", message: "Test SMS queued for sending", message_id: sms.message_id, sms_status: sms.status } rescue StandardError => e Rails.logger.error "Test SMS failed: #{e.message}\n#{e.backtrace.join("\n")}" render json: { status: "error", message: e.message }, status: :internal_server_error end end end