Skip to content

Commit

Permalink
fix: delivery receipt parser (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
samnang authored Feb 28, 2023
1 parent bd1b350 commit c369a29
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 15 deletions.
7 changes: 7 additions & 0 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

import { program } from "commander";
import { createLogger, format, transports } from "winston";
import "@sentry/tracing";
import * as Sentry from "@sentry/node";

import SomlengClient from "../lib/somleng_client.js";
import HTTPServer from "../lib/http_server/index.js";
import { GoIPGateway, SMPPGateway, DummyGateway } from "../lib/gateways/index.js";

Sentry.init({
dsn: "https://b4c80554595b4e75a9904318a8fe005d@o125014.ingest.sentry.io/4504756942864384",
});

async function main() {
let options = {};
let gateway;
Expand Down Expand Up @@ -143,5 +149,6 @@ async function main() {

main().catch((error) => {
console.error(error);
Sentry.captureException(error);
process.exit(1);
});
2 changes: 0 additions & 2 deletions lib/gateways/dummy_gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ class DummyGateway {
#onSentCallback;
#onReceivedCallback;

constructor() {}

async connect() {
await setTimeoutAsync(1000);
console.log("DummyGateway.connect() was called");
Expand Down
34 changes: 34 additions & 0 deletions lib/gateways/smpp_delivery_receipt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const PATTERN = /^id:(?<messageId>[\w-]+)\ssub:(?<sub>\d+)\sdlvrd:(?<dlvrd>\d+).+stat:(?<stat>\w+)/;

class InvalidMessageFormatError extends Error {}
class UnsupportedDeliveryStatusError extends Error {}

class SMPPDeliveryReceipt {
constructor(params) {
this.messageId = params.messageId;
this.status = params.status;
}

static parse(message) {
const matches = message.match(PATTERN);

if (matches === null) {
throw new InvalidMessageFormatError("Invalid Delivery Message Format");
}

let result = { messageId: matches.groups.messageId };
if (matches.groups.stat === "DELIVERED" || matches.groups.stat === "DELIVRD") {
result.status = "delivered";
} else if (matches.groups.stat === "ENROUTE" || matches.groups.stat === "ENROUTE") {
result.status = "sent";
} else if (matches.groups.stat === "UNDELIVERABLE" || matches.groups.stat === "UNDELIV") {
result.status = "failed";
} else {
throw new UnsupportedDeliveryStatusError("Unsupported Delivery Status Error");
}

return new SMPPDeliveryReceipt(result);
}
}

export { SMPPDeliveryReceipt, InvalidMessageFormatError, UnsupportedDeliveryStatusError };
28 changes: 21 additions & 7 deletions lib/gateways/smpp_gateway.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import * as Sentry from "@sentry/node";
import smpp from "smpp";
import {
SMPPDeliveryReceipt,
InvalidMessageFormatError,
UnsupportedDeliveryStatusError,
} from "./smpp_delivery_receipt.js";

class SMPPGateway {
#onSentCallback;
Expand Down Expand Up @@ -60,19 +66,27 @@ class SMPPGateway {

#handleMessageDeliveryReceipt() {
this.#session.on("deliver_sm", (pdu) => {
const rawMessage = pdu.short_message.message;

if (pdu.esm_class === smpp.ESM_CLASS.MC_DELIVERY_RECEIPT) {
const matches = pdu.short_message.message.match(
/^id:(?<messageId>\d+)\ssub:(?<sub>\d+)\sdlvrd:(?<dlvrd>\d+)/
);
const deliveryReceipt = { messageId: matches.groups.messageId };
deliveryReceipt.status = Number(matches.groups.dlvrd) > 0 ? "sent" : "failed";
this.#onSentCallback && this.#onSentCallback(deliveryReceipt);
try {
const deliveryReceipt = SMPPDeliveryReceipt.parse(rawMessage);
this.#onSentCallback && this.#onSentCallback(deliveryReceipt);
} catch (error) {
if (
error instanceof InvalidMessageFormatError ||
error instanceof UnsupportedDeliveryStatusError
) {
Sentry.captureException(error, { extra: { rawMessage: rawMessage } });
console.log("Unsupported delivery receipt message: ", rawMessage);
}
}
} else {
this.#onReceivedCallback &&
this.#onReceivedCallback({
source: pdu.source_addr,
destination: pdu.destination_addr,
shortMessage: pdu.short_message.message,
shortMessage: rawMessage,
});
}
});
Expand Down
154 changes: 148 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"license": "MIT",
"dependencies": {
"@anycable/core": "^0.5.7",
"@sentry/node": "^7.39.0",
"@sentry/tracing": "^7.39.0",
"commander": "^9.4.1",
"smpp": "^0.6.0-rc.4",
"winston": "^3.8.2",
Expand Down
Loading

0 comments on commit c369a29

Please sign in to comment.