How to Pull All Undelivered Messages using Python & PHP

A common need with message campaigns involves pulling all of the undelivered messages for further analysis. This guide will show how you can use the SignalWire Python SDK and SignalWire PHP SDK in order to do exactly that.

To quickly run this code, check out the recipe below for the easily copyable script in both PHP and Python. Or, keep reading below for a step-by-step code walkthrough!

How to Pull Undelivered Messages using Python

What do we need to run this code?

For the following code to work, you will need to have pandas, DateTime, and the SignalWire Python SDK installed.

Read about the different ways to install pandas here.

Read about DateTime and how to install using pip here.

Read about the SignalWire Python SDK and how to install here.

Code Walkthrough

We will start by importing the necessary resources. In this example, that is DateTime, pandas, and the SignalWire Client. We also need to instantiate the SignalWire client using the project ID, auth token, and space URL.

from datetime import datetime
from signalwire.rest import Client as signalwire_client
import pandas as pd

client = signalwire_client("ProjectID", "AuthToken", signalwire_space_url = 'SpaceURL')

As this script involves pulling all messages and then filtering out the ones that are undelivered, it's very important to try and narrow down the results by using a date range, From numbers, or To numbers. DateSent is a DateTime object where the order for the arguments is Year, Month, Date, Hour, Minute, Seconds. You can leave hour, minute, and seconds at 0, unless you have a specific time of day you would like to filter by.

📘

Octal Literals in Some Python Versions

For months Jan - September, A slight change was made because python version (3.9) does not support leading 0's in datetime anymore. You must use the 0o prefix for octal literals now. That is reflected below in the code. If your version doesn’t include that limitation, you can switch it back to 01 or whatever month you need.

The example below will show how to find all the messages within a specific date range that were sent from a specific From number.

messages = client.messages.list(date_sent_after=datetime(2021, 10, 20),
                                date_sent_before=datetime(2021, 10, 30)
                                from_="+1xxxxxxxxxx",
                                )

In the next section we will create an empty array d to keep track of our message data. We will loop through all the returned messages from the previous section and check for those where the status is undelivered. When a matches this condition, we will insert the data into the d array.

d = []

for record in messages:
    if record.status == "undelivered":
        d.append((record.from_, record.to, record.date_sent, record.sid, record.error_code))

You can expand this to include as many or as few parameters as you'd like. To see all of the parameters returned in the JSON response, you can view our API documentation here: List Messages API

Next, we will create a dataframe using pandas with column name headers. It's important to make sure that the order of the headers matches the order of the parameters you inserted into the array above. If you choose to add more or remove parameters, make sure to double-check that the order matches or your data will be mismatched in the CSV.

Lastly, we will print the dataframe for debugging purposes and export it to CSV. Using the parameter index=False turns off the indexing for each row.

df = pd.DataFrame(d, columns=('From', 'To', 'Date', 'MessageSID', 'Error Code'))

print(df)

df.to_csv('UndeliveredMessages.csv', index=False, encoding='utf-8')

How to Pull Undelivered Messages using PHP

What do we need to run this code?

For the following code to work, you will need to have the SignalWire PHP SDK installed. Read about the SignalWire PHP SDK and how to install here.

You will also need to make sure that the vendor/autoload.php path points to the correct location on your computer, as we can’t determine that for you. However, if you want to run this script exactly, install the SDK from within the folder that contains this PHP script.

Code Walkthrough

First, we need to import the necessary resources. In this example, that just means we need to point to the correct path of the vendor autoload file on your computer. We also need to instantiate the SignalWire client using the project ID, auth token, and space URL.

<?php

require './vendor/autoload.php';
use SignalWire\Rest\Client;
$client = new Client("ProjectID", "AuthToken", array("signalwireSpaceUrl" => "YOURSPACE.signalwire.com"));

Next, we need to choose what parameters we'd like to filter by. In this example, I have filtered by a date range and a from number to help narrow down the returned results. Depending on the volume of messaging that you send, you may have to restrict your date range down further so that you don't hit any memory allocation errors.

$messages = $client->messages->read([
    "dateSentAfter" => "2021-04-01",
    "dateSentBefore" => "2021-04-20",
    'from' => '+1xxxxxxxxxx', 
]);

In the next section, we need to create the file to insert the message data into.
Begin by writing headers and storing them in a variable called $fields. We also use implode to join the elements of the array with a string. We will then use fopen to create and open a file named TodaysDate_MessageReport. After that, we use fputcsv to insert our headers stored in $fields into our file.

$fields = array('Message SID', 'From', 'To', 'Date Sent', 'Status', 'Direction', 'Price');
echo '"'.implode('","', $fields).'"'."\n";

$fp = fopen(date("Y-m-d").'_messageReport.csv', 'w');

fputcsv($fp, $fields);

Next, we need to loop through our $messages array in order to gather the necessary message data. We will first check each message record to see what the message status is. If the status is undelivered, we will insert the message record into our CSV.

It is important to make sure the order of the headers is the same as the order of the values we will be gathering. As we loop through each message record, we will insert it into the CSV one by one and use implode to join the elements of the array with a string. The last step is to close the file!

foreach ($messages as $message) {
    if ($message->status = "undelivered")
        $row = array(
            $message->sid, 
            $message->from, 
            $message->to, 
            $message->dateSent->format('Y-m-d H:i:s'), 
            $message->status, 
            $message->direction, 
            $message->price,
        );
  
        fputcsv($fp, $row);

        echo '"'.implode('","', $row).'"'."\n";
}

fclose($fp);

Did this page help you?