вторник, 22 августа 2017 г.

SMPP for Go developers and not only

FAQ about SMPP
  1. Q: How to get notification on subscriber availability using HLR

    A:
    An ESME may use the set_dpf parameter [in the submit_sm] to request the setting of a delivery pending flag (DPF) for certain delivery failure scenarios, such as MS [i.e. Mobile Station] unavailability (as indicated by the HLR). The MC [i.e. Message Center] should respond to such a request with an alert_notification PDU when it detects that the destination MS has become available. For more information see https://www.activexperts.com/sms-component/sms/smpptlv/
  2. Q: Каковы преимущества использования SMPP

    A: 
  3. - стандартный протокол (не придется переписывать бек-энд при смене SMS-шлюза)
    - асинхронность, высокая пропускная способность
    - отправка сообщений происходит практически мгновенно
    - оперативная доставка статуса доставки и ошибок и бОльшая информативность,
    точность времени доставки до минуты
    - возможность проверка номера и дислокации абонента при помощи HLR-запроса (напр. есть такие ошибки как "Абонент не существует", "Абонент не в сети", "Абонент заблокирован")

  4. Q: What are the advantages of SMPP

    A: 
  5. - This is a standard industrial protocol, no need to rewrite back-end if you move to another SMPP provider / ESME
    - Asynchrony, high throughput
    - Sending messages is almost instantaneous
    - Prompt delivery of delivery status, submit errors are more informative, delivery time accuracy up to a minute
    - The ability to check the number and location of the subscriber using HLR-request (eg there are such errors as "Subscriber does not exist", "Subscriber is offline", "Subscriber is blocked")

  6. Q: How to get ESME status of sent message immediately / SMPP implementaion by fiorix.

    A:
  7. sm, err = c.tx.Submit(m)
    if err == nil {
        log.Println("Send > ID:", sm.RespID())
    } else {
        log.Println("Send > err", c.err)
        if sm != nil {
            s:= uint32(sm.Resp().Header().Status)
            log.Println("Send > err #", s)
        }
    }

  8. Q: How to check if transmitter is bound ? / SMPP implementaion by fiorix
    I want to restrict Send() of message during reconnects. Because if Bind of Tranciever coincide with Submit_SM it causes Bind to fail -- SMSC does not answer on Bind.

      A: Solution:
      conn_st_ch := c.tx.Bind()
      go func() {
          for {
              select {
              case conn_st := <-conn_st_ch:
                  c.bound = conn_st.Status() == smpp.Connected
                  log.Println("bound>", c.bound, c.id)
              }
          }
      }()
      

      Note: It works because of the non-blocking nature of signal sent from client::notify
    1. Q: What software I can use for Tests / Debug / Simulation of SMPP gateway ?

      A:
      I recommend ActiveXPerts SMPP simulator. However it doesn't work under wine.
    2. Q: How to parse short message from deliver_sm_resp

      A: for JavaScript
      var re_key = /(\w+(\s\w+)?)/
      var re_val = /(\w+|[0-9a-f]+|null|\-)|(\s+|$)/
      re_key.compile(re_key);
      re_val.compile(re_val);
      
      // examples:
      //id:327 sub:001 dlvrd:001 submit date:1506272148 done date:1506272148 stat:DELIVRD err:null text:-'
      //id:c449ab9744f47b6af1879e49e75e4f40 sub:001 dlvrd:0 submit date:0610191018 done date:0610191018 stat:ACCEPTD err:0 text:This is an Acti
      //id:7220bb6bd0be98fa628de66590f80070 sub:001 dlvrd:1 submit date:0610190851 done date:0610190951 stat:DELIVRD err:0 text:This is an Acti
      //id:b756c4f97aa2e1e67377dffc5e2f7d9b sub:001 dlvrd:0 submit date:0610191211 done date:0610191211 stat:REJECTD err:1 text:This is an Acti
      //id:bd778cd76ae9e79da2ddc8188c68f8c1 sub:001 dlvrd:0 submit date:0610191533 done date:0610191539 stat:UNDELIV err:1 text:This is an Acti
      //
      //Field  Meaning
      //id  The message reference of the message.
      //    sub  Sub-ID, not used.
      //    dlvrd  Value '1' when the message has been delivered, if the message is still pending '0'.
      //    submit date  Submission date and time.
      //    done date  Date and time the status has changed, or message delivery time when stat is set to 'DELIVRD'.
      //    stat  Current status of the message.
      //    err  Additional error code, provider specific.
      //    text  Part of the original message text.
      
      module.exports.short_msg_parse = function(msg) {
          obj = {};
          var s = msg//.toLowerCase();
          for (;;) {
              var i = s.indexOf(':');
              if (i <= 0) break;
              var f = s.slice(0, i);
              if (k = f.match( re_key )) {
                  var key = k[1];
                  s = s.slice(i + 1);
                  if (v = s.match( re_val )) {
                      i = v[0].length;
                      s = s.slice(i);
                      obj[key] = v[1];
                  } else
                      break;
              } else
                  break;
          }
      
          // TODO: validate field names
      
      FIELDS = [ 'id', 'sub', 'dlvrd', 'submit date', 'done date', 'stat', 'err', 'text' ]; return obj; }



    3. Q: How to parse done date in short message from deliver_sm_resp

      A: for JavaScript
      // possible date formats:
      // yyMMddHHmm
      // yyMMddHHmmss
      // yyyyMMddHHmmss
      module.exports.smppDate_toLocalDate = function (str) {
          var _size = Math.ceil(str.length / 2),
              _ret  = new Array(_size),
              _offset;
      
          for (var _i=0; _i<_size; _i++) {
              _offset = _i * 2;
              _ret[_i] = Number(str.substring(_offset, _offset + 2));
          }
      
          _ret[0] += 2000;
          _ret[1] -= 1;
          return utils.applyToConstructor(Date, _ret);
      }
      

    4. Q: What routing restrictions do countries have ?

      A:
      USA -- Please use E.164 format, as 14087525280 , additionally apart from the fact that the number appears to be a landline, for USA traffic you need to follow the guidance in this article. To summarise for USA traffic: * For P2P traffic you will need to use a Nexmo virtual number as sender. * For A2P traffic you will need to use either a Short Code or a Toll Free number/

      China

      France -- When sending to France with alpha sender IDs you must include within the message "STOP SMS AU 36184".

    External links