Delivery Receipt
Receipt format
Often you want to get delivery status for an SMS message. SMPP protocol provides the ability to request a delivery receipt in PDU submitted. There are two ways how you can do it with the InetLab.SMPP library.
submitSm.RegisteredDelivery = 1;
// or
submitSm.SMSCReceipt = SMSCDeliveryReceipt.SuccessOrFailure;
or
var resp = await client.SubmitAsync(
SMS.ForSubmit()
.From("short_code")
.To("436641234567")
.DeliveryReceipt()
.Text("test text")
);
As a result the SMPP-server will deliver the receipt to the client application. On the client side it can be received using evDeliverSm event. Delivery receipt format is SMSC vendor specific, but typical format is
id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DDDDDDD err:E Text: . . . . . . . . .
This text format is represented in the library as Receipt class.
It has the following properties:
MessageId - The message ID allocated to the message by the SMSC when originally submitted. You can get it from SubmitSmResp or SubmitMultiResp.
Submitted - Number of short messages originally submitted. This is only relevant when the original message was submitted to a distribution list within SubmitMulti.
Delivered - Number of short messages delivered to a distribution list with SubmitMulti.
SubmitDate - The time and date at which the short message was submitted.
DoneDate - The time and date at which the short message reached its final state.
ErrorCode - Network specific error code or an SMSC error code for the attempted delivery of the message.
Text - The first 20 characters of the short message.
State - The final status of the message. The value could be one of the following:
State | Description |
---|---|
Delivered | Message is delivered to the destination |
Expired | Message validity period has expired |
Deleted | Message has been deleted |
Undeliverable | Message is undeliverable |
Accepted | Message is in accepted state (i.e. has been manually read on behalf of the subscriber by customer service) |
Unknown | Message is in invalid state |
Rejected | Message is in a rejected state |
Note
Library sends DeliverSmResp with status ESME_RX_T_APPN to SMPP server when evDeliverSm event handler method throws an exception.
How to tie submitted message with delivery receipt
SMS message in SMPP protocol is actually represented as one or many PDUs. When text is longer that 140 octets library sends text as concatenated SMS parts (PDU). One part can be represented as SubmitSm class or SubmitMulti class.
Before sending SubmitSm or SubmitMulti PDU you need to assign Sequence number to it.
public async Task SendMessage(TextMessage message)
{
IList<SubmitSm> list = SMS.ForSubmit()
.From(_config.ShortCode)
.To(message.PhoneNumber)
.Text(message.Text)
.DeliveryReceipt()
.Create(_client);
foreach (SubmitSm sm in list)
{
sm.Header.Sequence = _client.SequenceGenerator.NextSequenceNumber();
_clientMessageStore.SaveSequence(message.Id, sm.Header.Sequence);
}
var responses = await _client.SubmitAsync(list);
foreach (SubmitSmResp resp in responses)
{
_clientMessageStore.SaveMessageId(message.Id, resp.MessageId);
}
}
At the same time you need to store Sequence in the database. For one message.Id you need to store several Sequence.
In response to SubmitSm PDU your application receives SubmitSmResp PDU. This response has the same Sequence number and MessageId generated by the server.
When you receive a delivery receipt in the event evDeliverSm, the server sends same MessageId which you can use for updating status of the submitted SMS text.
private void ClientOnEvDeliverSm(object sender, DeliverSm data)
{
if (data.MessageType == MessageTypes.SMSCDeliveryReceipt)
{
_clientMessageStore.UpdateMessageStatus(data.Receipt.MessageId, data.Receipt.State);
}
}
SMS Text considered as delivered when all sms parts are in Delivered state.
For this purpose you can create 2 tables in the database.
- outgoing_messages for all outgoing SMS messages
name | description |
---|---|
messageId | id of the message |
messageText | long message text |
- outgoing_message_parts for all PDUs generated for each message
name | description |
---|---|
messageId | reference to messageId field in the outgoing_messages |
sessionId | any unique id generated when SmppClient connects to the server. sequenceNumber is unique only in one SMPP session. |
sequenceNumber | number generated before sending PDU |
serverMessageId | message id received from the server. |
status | status received in the delivery receipt |
Reade more on page "Track message sending and delivery"