Search code examples
ruby-on-railssmssmpp

Using Smpp in Ruby on Rails


The need to send and receive SMS messages via Smpp, Register Number, received systemID and password, but fails to connect. Connected to the project gem 'ruby-smpp', to use the example of the getaway this, it only changed the values ​​systemID and password.

in the logs:

<- (BindTransceiver) len = 37 cmd = 9 status = 0 seq = 1364360797 (<systemID><password>)
Hex dump follows:
<- 00000000: 0000 0025 0000 0009 0000 0000 5152 7e5d | ...% ........ QR ~]
<- 00000010: 3531 3639 3030 0068 4649 6b4b 7d7d 7a00 | <systemID>.<password>.
<- 00000020: 0034 0001 00 | .4 ...

Starting enquire link timer (with 10s interval)
Delegate: transceiver unbound

in the console:

Connecting to SMSC ...
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..
MT: Disconnected. Reconnecting in 5 seconds ..

Tell me, please, I do not, maybe in the config to something else to add or change? And smpp connection, as I understand, it works only with a specific IP-address, but the logs on the server and on the local machine are the same

class Gateway
  include KeyboardHandler

  # MT id counter. 
  @@mt_id = 0

  # expose SMPP transceiver's send_mt method
  def self.send_mt(*args)
    @@mt_id += 1
    @@tx.send_mt(@@mt_id, *args)
  end

  def logger
    Smpp::Base.logger
  end

  def start(config)
    # The transceiver sends MT messages to the SMSC. It needs a storage with Hash-like
    # semantics to map SMSC message IDs to your own message IDs.
    pdr_storage = {} 

    # Run EventMachine in loop so we can reconnect when the SMSC drops our connection.
    puts "Connecting to SMSC..."
    loop do
      EventMachine::run do
        @@tx = EventMachine::connect(
          config[:host], 
          config[:port], 
          Smpp::Transceiver, 
          config, 
          self    # delegate that will receive callbacks on MOs and DRs and other events
        )
        print "MT: "
        $stdout.flush

        # Start consuming MT messages (in this case, from the console)
        # Normally, you'd hook this up to a message queue such as Starling
        # or ActiveMQ via STOMP.
        EventMachine::open_keyboard(KeyboardHandler)
      end
      puts "Disconnected. Reconnecting in 5 seconds.."
      sleep 5
    end
  end

  # ruby-smpp delegate methods 

  def mo_received(transceiver, pdu)
    logger.info "Delegate: mo_received: from #{pdu.source_addr} to #{pdu.destination_addr}: #{pdu.short_message}"
  end

  def delivery_report_received(transceiver, pdu)
    logger.info "Delegate: delivery_report_received: ref #{pdu.msg_reference} stat #{pdu.stat}"
  end

  def message_accepted(transceiver, mt_message_id, pdu)
    logger.info "Delegate: message_accepted: id #{mt_message_id} smsc ref id: #{pdu.message_id}"
  end

  def message_rejected(transceiver, mt_message_id, pdu)
    logger.info "Delegate: message_rejected: id #{mt_message_id} smsc ref id: #{pdu.message_id}"
  end

  def bound(transceiver)
    logger.info "Delegate: transceiver bound"
  end

  def unbound(transceiver)  
    logger.info "Delegate: transceiver unbound"
    EventMachine::stop_event_loop
  end

end


module KeyboardHandler
  include EventMachine::Protocols::LineText2

  def receive_line(data)
    sender, receiver, *body_parts = data.split
    unless sender && receiver && body_parts.size > 0
      puts "Syntax: <sender> <receiver> <message body>"      
    else
      body = body_parts.join(' ')
      puts "Sending MT from #{sender} to #{receiver}: #{body}"  
      SampleGateway.send_mt(sender, receiver, body)
    end
    prompt
  end

  def prompt
    print "MT: "
    $stdout.flush
  end
end

/initializers

require 'eventmachine'
require 'smpp'

LOGFILE = Rails.root + "log/sms_gateway.log"
Smpp::Base.logger = Logger.new(LOGFILE)

/script

puts "Starting SMS Gateway. Please check the log at #{LOGFILE}"
config = {
  :host => '127.0.0.1',
  :port => 6000,
  :system_id => <SystemID>,
  :password => <Password>,
  :system_type => '', # default given according to SMPP 3.4 Spec
  :interface_version => 52,
  :source_ton  => 0,
  :source_npi => 1,
  :destination_ton => 1,
  :destination_npi => 1,
  :source_address_range => '',
  :destination_address_range => '',
  :enquire_link_delay_secs => 10
}
gw = Gateway.new
gw.start(config)

file from the script / run through the rails runner


Solution

  • Problem solved. Initially were incorrectly specified host and port, as smpp-server was not on the same machine as the RoR-application. As for encoding, sending in Russian layout should be

    message = text.encode ("UTF-16BE"). force_encoding ("BINARY")
    Gateway.send_mt (sender, receiver, message, data_coding: 8)
    

    To receive a form in the right

    message = pdu.short_message.force_encoding ('UTF-16BE'). encode ('UTF-8')