Skip to main content

Triggers

The SMPP connector supports event-driven integration where the SMSC pushes mobile-originated messages and delivery receipts to a registered Ballerina service.

Two components work together:

ComponentRole
smpp:ListenerBinds to the SMSC as RECEIVER or TRANSCEIVER and manages the session
smpp:CallerInjected into a transceiver-bound service's handler to reply on the same session

For action-based operations, see the Action Reference.


Listener​

The smpp:Listener binds as RECEIVER (inbound only) or TRANSCEIVER (inbound + reply via Caller), and dispatches every inbound deliver_sm/data_sm to the attached service.

Configuration​

The host, systemId, and password used to bind are required parameters of the listener's initialization, ahead of the rest of the configuration below.

ListenerConfig (selected fields):

FieldTypeDefaultDescription
portint2775SMSC port
bindTypeRECEIVER|TRANSCEIVERRECEIVERThe bind mode. TRANSCEIVER additionally allows replying via Caller
maxConcurrentDispatchint3Maximum number of inbound PDUs dispatched to the attached service concurrently
responseModeSYNC|ASYNCSYNCControls when the deliver_sm_resp/data_sm_resp is sent back to the SMSC
rebindPolicyRebindPolicyControls automatic rebinding after an unexpected session drop
secureSocketSecureSocket|InsecureSocket?()Transport security. Absent means plaintext TCP

Initializing the listener​

import ballerina/smpp;

configurable string systemId = ?;
configurable string password = ?;

listener smpp:Listener smsListener = check new ("smsc.example.com", systemId, password,
port = 2775, bindType = smpp:RECEIVER);

Service​

A service attached to an smpp:Listener implements one or more of the callbacks below. One service per listener.

Callbacks​

CallbackSignatureDescription
onDeliverSmremote function onDeliverSm(smpp:Sms sms) returns error?Invoked for an inbound deliver_sm: a mobile-originated message or a delivery receipt
onDataSmremote function onDataSm(smpp:Sms sms) returns error?Invoked for an inbound data_sm
onErrorremote function onError(error err) returns error?Invoked on an unexpected session drop
note

In SYNC response mode (the default), an error returned from onDeliverSm/onDataSm becomes a negative response telling the SMSC the message was not handled; most SMSCs treat this as a signal to redeliver. In ASYNC mode, the SMSC is acknowledged immediately and a later handler failure is only logged, never reflected back to the SMSC.

Full example: receive only​

import ballerina/io;
import ballerina/smpp;

configurable string systemId = ?;
configurable string password = ?;

listener smpp:Listener smsListener = check new ("smsc.example.com", systemId, password,
port = 2775, bindType = smpp:RECEIVER);

service on smsListener {
remote function onDeliverSm(smpp:Sms sms) returns error? {
if sms.deliveryReceipt {
io:println(string `Delivery receipt: ${sms.receipt?.finalStatus ?: "unparsed"}`);
} else {
io:println(string `SMS from ${sms.sourceAddress}: ${sms.shortMessage}`);
}
}
}

Replying with Caller​

A TRANSCEIVER-bound listener can declare an smpp:Caller parameter (matched by type, in either parameter order) and reply on the same session:

listener smpp:Listener replyListener = check new ("smsc.example.com", systemId, password,
port = 2775, bindType = smpp:TRANSCEIVER);

service on replyListener {
remote function onDeliverSm(smpp:Sms sms, smpp:Caller caller) returns error? {
smpp:SubmitResult result = check caller->submit({
destinationAddress: sms.sourceAddress,
shortMessage: "Thanks for your message!"
});
}
}
note

Correlate a later delivery receipt against a submit using sms.receiptedMessageId (the receipted_message_id TLV), the only field SMPP guarantees for this; the Appendix-B receipt body's own id is vendor specific.

Supporting types​

The records below are what the listener hands to your service callbacks.

Sms​

FieldTypeDescription
sourceAddressstringSender address
destinationAddressstringReceiver address
shortMessagestringThe decoded message payload
shortMessageBytesbyte[]The same payload as raw undecoded bytes
deliveryReceiptbooleantrue when this PDU is an SMSC delivery receipt rather than a mobile-originated message
receiptedMessageIdstring?The guaranteed correlation key between a delivery receipt and a submit's messageId
receiptDeliveryReceipt?The parsed delivery receipt, when deliveryReceipt is true and the body could be parsed
propertiesmap<anydata>Raw PDU attributes for callers that need them: dataCoding, esmClass, udhi, and the source/destination TypeOfNumber and NumberingPlanIndicator values

DeliveryReceipt​

FieldTypeDescription
idstring?The SMSC message ID quoted in the receipt text (id:); prefer Sms.receiptedMessageId for correlation
submittedint?Number of messages originally submitted (sub:)
deliveredint?Number of messages delivered (dlvrd:)
finalStatusDeliveryReceiptStatus?The final delivery state (stat:)
submitDatestring?Original submission time (yyMMddHHmm, no timezone)
doneDatestring?Final-state time (yyMMddHHmm, no timezone)
errorCodestring?A network/SMSC-specific error code (err:)
textstring?A short echo of the original message (Text:)

Every DeliveryReceipt field is optional: SMSCs vary in which parts of the Appendix B receipt format they include, and a field that was not present in the receipt text is absent rather than defaulted.