- product:messaging - language:python - language:nodejs - language:php - sdk:compatibility ## Overview With this code snippet you can get the total cost of messaging in a specific date range. Full code example: How to Use List Messages API to Get Price Stats python from datetime import datetime from signalwire.rest import Client as signalwire_client import pandas as pd client = signalwire_client(ProjectID, AuthToken, signalwire_space_url=YourSpace.signalwire.com) messages = client.messages.list(date_sent_after=datetime(2021, 10, 1), date_sent_before=datetime(2021, 10, 31)) d = [] status = [] for record in messages: d.append((record.from_, record.to, record.date_sent, record.sid, record.price, record.direction, record.status)) status.append(record.status) total_sent=int(status.count(sent)) total_received=int(status.count(received)) total_delivered=int(status.count(delivered)) total_undelivered=int(status.count(undelivered)) num_outbound_messages = total_sent + total_delivered + total_undelivered num_inbound_messages = total_received df = pd.DataFrame(d, columns=(From, To, Date, MessageSID, Price, Message Direction, Message Status)) print(df) df.to_csv(Messages.csv, index=False, encoding=utf-8) print() totalMess = len(df) totalCost = df[Price].sum() formattedCost = ${:,.2f}.format(totalCost) print(You sent + str(totalMess) + total messages during your selected date range.) print(The total cost of messages in your selected date range is approximately + formattedCost + USD.) print(There were + str(total_delivered) + delivered messages and + str(total_undelivered) + undelivered messages.) print(There were + str(num_inbound_messages) + inbound messages and + str(num_outbound_messages) + outbound messages.) js const dfd = require(danfojs); const fs = require(fs); const { RestClient } = require(@signalwire/compatibility-api); // TODO: Update with your credentials let space_url = YOURSPACENAME.signalwire.com; let project_id = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX; let access_token = PTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx const client = RestClient( project_id, access_token, { signalwireSpaceUrl: space_url} ); let data = []; let total_sent = 0; let total_received = 0; let total_delivered = 0; let total_undelivered = 0; const getMessageList = client.messages.list({ dateSentAfter: new Date(Date.UTC(2022, 02, 10)), dateSentBefore: new Date(Date.UTC(2022, 04, 26)), }); getMessageList.then((messages) => { messages.forEach(message => { data.push([ message.from, message.to, message.dateSent, message.sid, message.price, message.direction, message.status ]); switch (message.status) { case sent: total_sent++; break; case received: total_received++; break; case delivered: total_delivered++; break; case undelivered: total_undelivered++; break; } }); let num_outbound_messages = total_sent + total_delivered + total_undelivered; let num_inbound_messages = total_received; let all_data = new dfd.DataFrame(data, { columns: [From, To, Date, MessageSID, Price, Message Direction, Message Status], config: { tableDisplayConfig: { columns: [ { width: 3 }, { width: 13 }, { width: 13 }, { width: 36}, { width: 36 }, { width: 13 }, { width: 12 }, { width: 16} ], }, tableMaxRow: 1000 }, }); let totalMessages = data.length; let totalCost = all_data[Price].sum().toFixed(2); console.log(You sent + totalMessages + total messages during your selected date range.); console.log(The total cost of messages in your selected date range is approximately + totalCost + USD.); console.log(There were + total_delivered + delivered messages and + total_undelivered + undelivered messages.); console.log(There were + num_inbound_messages + inbound messages and + num_outbound_messages + outbound messages.); all_data.print(); fs.writeFileSync(Messages.csv, dfd.toCSV(all_data)); }) php YOURSPACENAME.signalwire.com)); // Write Headers for output CSV. $header_fields = array(From, To, Date Sent, Message SID, Price, Direction,Status,); echo .implode(,, $header_fields)..\n; // Open File named Messages.csv $fp = fopen(Messages.csv, w); // Insert headers into output Messages.csv file. fputcsv($fp, $header_fields); // Define some variables for tracking $total_cost=0; $total_sent=0; $total_rec=0; $total_delivered=0; $total_undelivered=0; $total_messages=0; $num_outbound_msg=0; $num_inbound_msg=0; // Can filter message by whatever parameters you need. This example is any message sent after January 1, 2022. $messages = $client->messages->read([ dateSentAfter => 2022-01-01, dateSentBefore => 2022-04-29, ]); // Write rows foreach ($messages as $message) { $row = array( $message->from, $message->to, $message->dateSent->format(Y-m-d H:i:s), $message->sid, $message->price, $message->direction, $message->status, ); $total_cost += $message->price; if ($message->status == sent) { $total_sent++; $total_messages++; } else if ($message->status == received) { $total_rec++; $total_messages++; } else if ($message->status == failed || $message->status == undelivered) { $total_undelivered++; $total_messages++; } else if ($message->status == delivered) { $total_delivered++; $total_messages++; } // Insert rows into CSV fputcsv($fp, $row); echo .implode(,, $row)..\n; } $num_outbound_msg=$total_sent+$total_delivered+$total_undelivered; $num_inbound_msg=$total_rec; $formatted_cost=new NumberFormatter(en_US,NumberFormatter::CURRENCY); $formatted_cost->setTextAttribute( $formatted_cost::CURRENCY_CODE, USD ); $formatted_cost->setAttribute( $formatted_cost::FRACTION_DIGITS, 2 ); $numberString = $formatted_cost->format( $total_cost ); print There were . $total_messages . total messages during your selected date range.\n; print The total cost of messages in your selected date range is approximately . $numberString . USD.\n; print There were . $total_delivered . delivered messages and . $total_undelivered . undelivered messages.\n; print There were . $num_inbound_msg . inbound messages and . $num_outbound_msg . outbound messages.\n; // close file fclose($fp); java import io.github.olajhidey.SignalWireClient; import io.github.olajhidey.model.message.Message; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class MessageSummary { public static List dataLines = new ArrayList<>(); public static SignalWireClient client() { return new SignalWireClient(YOUR-PROJECT-ID, YOUR-API-TOKEN, YOUR-SPACE-NAME); } public static void main(String[] args) { List messages = client().message().getMessages().messages; int delivered = 0; int undelivered = 0; int sent = 0; int received = 0; double price = 0d; dataLines.add(new String[]{From, To, Date, Status, MessageSID}); for (Message message : messages) { dataLines.add(new String[]{message.from, message.to, message.date_created, message.to, message.sid}); if (message.price != null) { price += Double.parseDouble(message.price); } switch (message.status) { case sent: sent += 1; break; case delivered: delivered += 1; break; case undelivered: undelivered += 1; break; case received: received += 1; break; default: System.out.println(Something went wrong); } } String totalMessage = String.format(You sent %d total messages on your space, messages.size()); String priceSummary = String.format(The total cost of messages in your selected date range is approximately %,.2f USD, price); String messageStatus = String.format(There were %d delivered messages and %d undelivered messages., delivered, undelivered); String messageRecipient = String.format(There were %d inbound messages and %d outbound messages., received, sent); System.out.println(totalMessage); System.out.println(priceSummary); System.out.println(messageStatus); System.out.println(messageRecipient); try { createAndPopulateCSV(); } catch (IOException ioException) { ioException.printStackTrace(); } } public static String convertToCsv(String[] data) { return Stream.of(data) .map(MessagesList::escapeSpecialCharacters) .collect(Collectors.joining(,)); } public static void createAndPopulateCSV() throws IOException { // Auto-generate the name of the file String filename = message_result + System.currentTimeMillis(); // Get the absolute path to the folder you would like to create in the project directory File file = new File(Paths.get(csv).toAbsolutePath().toUri()); // if file doesnt exist. create a new folder if (!file.exists()) { boolean isFolder = file.mkdir(); if (isFolder) { System.out.println(New folder created!); } else { System.out.println(Couldn\t create folder); } } // create new csv file with the autogenerated name File csvOutputFile = new File(Paths.get(csv).toAbsolutePath() + \\ + filename); try (PrintWriter printWriter = new PrintWriter(csvOutputFile)) { dataLines.stream() .map(MessageSummary::convertToCsv) .forEach(printWriter::println); // Write item into the CSV file System.out.println(Write operation done successfully!); } } public static String escapeSpecialCharacters(String data) { String escapeData = data.replace(\\R, ); if (data.contains(,) || data.contains(\)) { data = data.replace(\, \\); escapeData = \ + data + \; } return escapeData; } } ## Python ### What do I 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](https://pandas.pydata.org/docs/getting_started/install.html). Read about DateTime and how to install using pip [here](https://pypi.org/project/DateTime/). Read about the SignalWire Python SDK and how to install [here](/compatibility-api/sdks). ### Code Walkthrough #### Load the necessary libraries and instantiate the SignalWire Client 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. python 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) #### Select time frame to filter by In this example, I have included how to filter by DateSentAfter and DateSentBefore to return all messages between a specific date range. 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. python messages = client.messages.list(date_sent_after=datetime(2021, 10, 1), date_sent_before=datetime(2021, 10, 31)) :::info Octal Literals in Some Python Versions For months Jan - September, A slight change was made because python version (3.9) does not support leading 0s 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. ::: #### Prepare data structures Next, we will create two arrays: d and status. d will contain all of the message records within the specified date range and status will contain only the message statuses which we will use to get some summarized stats. We will loop through each message record returned by the List Messages API and add additional detail to the row as well as adding the status alone to the status array. python for record in messages: d.append((record.from_, record.to, record.date_sent, record.sid, record.price, record.direction, record.status)) status.append(record.status) #### Prepare status counter variables Next we will categorize the message status for all our returned messages and count how many are inbound vs outbound. python # categorize message status for all returned messages total_sent=int(status.count(sent)) total_received=int(status.count(received)) total_delivered=int(status.count(delivered)) total_undelivered=int(status.count(undelivered)) # count how many are inbound vs outbound num_outbound_messages = total_sent + total_delivered + total_undelivered num_inbound_messages = total_received #### Print the results Now that all of the message data is stored in d, we need to convert it to a data frame to make for easier containment as well as the ability to convert to CSV. Its important to make sure that the column headers are in the same order as the message record details added to d. python # create dataframe and convert to CSV df = pd.DataFrame(d, columns=(From, To, Date, MessageSID, Price, Message Direction, Message Status)) print(df) df.to_csv(Messages.csv, index=False, encoding=utf-8) print() As we want to get the amount spent in our date range, we will add up the cost of the Price column in the dataframe and convert the float to a currency format. python totalMess = len(df) totalCost = df[Price].sum() formattedCost = ${:,.2f}.format(totalCost) Lastly, we will use the data and values that weve calculated to display the total cost as well as some summaries about delivery status and the message type distribution. print(You sent + str(totalMess) + total messages during your selected date range.) print(The total cost of messages in your selected date range is approximately + formattedCost + USD.) print(There were + str(total_delivered) + delivered messages and + str(total_undelivered) + undelivered messages.) print(There were + str(num_inbound_messages) + inbound messages and + str(num_outbound_messages) + outbound messages.) ## Node.js ### What do I need to run this code? We will need the following libraries (click their names to get instructions on how to install them): - [Danfo.js](https://www.npmjs.com/package/danfojs) - [fs](https://nodejs.org/api/fs.html) - there is no need to install this module, as it is part of the Node.js Core - [SignalWire Rest Client](https://www.npmjs.com/package/@signalwire/compatibility-api) ### How to Run Snippet? If you save this code snippet in a file called messagingPricingSummaries.js, for example, you then need to run: node messagingPricingSummaries.js. ### Code Walkthrough #### Load the necessary libraries javascript const dfd = require(danfojs); const fs = require(fs); const { RestClient } = require(@signalwire/compatibility-api); #### Instantiate the SignalWire Rest Client In order for us to connect to SignalWire later on in the code using the Rest Client we first need to make sure we update space_url, project_id, and access_token. javascript let space_url = YOURSPACENAME.signalwire.com; let project_id = XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX; let access_token = PTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; const client = RestClient(project_id, access_token, { signalwireSpaceUrl: space_url }); #### Create the necessary variables Here we create the data array, to which well add all message data as it is loaded, as well as variables that will serve as counters for each status. javascript let data = []; let total_sent = 0; let total_received = 0; let total_delivered = 0; let total_undelivered = 0; #### Get the message data for a given period In this section of the code we get the message list using client.messages.list(), and passing it the dateSentAfter and dateSentBefore parameters. Once we get the message list, we then add each message to the data array and increment the status counters depending on the message status. javascript const getMessageList = client.messages.list({ dateSentAfter: new Date(Date.UTC(2022, 02, 10)), dateSentBefore: new Date(Date.UTC(2022, 04, 26)), }); getMessageList.then((messages) => { messages.forEach(message => { data.push([ message.from, message.to, message.dateSent, message.sid, message.price, message.direction, message.status ]); switch (message.status) { case sent: total_sent++; break; case received: total_received++; break; case delivered: total_delivered++; break; case undelivered: total_undelivered++; break; } }); #### Prepare all data and print the results Once all messages have been parsed, we are ready to prepare the variables that will help make the final result more readable, such as the number of outbound messages as well as inbound. We create the all_data DataFrame, that will help up with printing the results to the terminal and to a CSV file. We also get the total number of messages for this period, and sum up the cost of the traffic. Finally, we print comprehensible results using the data we have gathered from all of the messages. Utilizing the all_data DataFrame we print a list of all messages from this period to the terminal and to a CSV file named Messages.csv. javascript let num_outbound_messages = total_sent + total_delivered + total_undelivered; let num_inbound_messages = total_received; let all_data = new dfd.DataFrame(data, { columns: [From, To, Date, MessageSID, Price, Message Direction, Message Status], config: { tableDisplayConfig: { columns: [ { width: 3 }, { width: 13 }, { width: 13 }, { width: 36}, { width: 36 }, { width: 13 }, { width: 12 }, { width: 16} ], }, tableMaxRow: 1000 }, }); let totalMessages = data.length; let totalCost = all_data[Price].sum().toFixed(2); console.log(You sent + totalMessages + total messages during your selected date range.); console.log(The total cost of messages in your selected date range is approximately + totalCost + USD.); console.log(There were + total_delivered + delivered messages and + total_undelivered + undelivered messages.); console.log(There were + num_inbound_messages + inbound messages and + num_outbound_messages + outbound messages.); all_data.print(); fs.writeFileSync(Messages.csv, dfd.toCSV(all_data)); }) ## PHP ### What do I need to run this code? We will need the following libraries (click their names to get instructions on how to install them): - [SignalWire Rest Client](/compatibility-api/sdks) - You will also need to make sure that the vendor/autoload.php path points to the correct location in 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. ### How to Run Snippet? If you save this code snippet in a file called messagingPricingSummaries.php, for example, you then need to run: php messagingPricingSummaries.php. ### Code Walkthrough #### Load the necessary libraries php YOURSPACENAME.signalwire.com)); #### Create the necessary variables Here we create the $header_fields array, to help the output CSV be more readable. Well also create some variables that will serve as counters for the different statuses, and total messages sent or received, as well as the total price. We also open the output file and write out our header row to it. php // Write Headers for output CSV. $header_fields = array(From, To, Date Sent, Message SID, Price, Direction,Status,); echo .implode(,, $header_fields)..\n; // Open File named Messages.csv $fp = fopen(Messages.csv, w); // Insert headers into output Messages.csv file. fputcsv($fp, $header_fields); // Define some variables for tracking $total_cost=0; $total_sent=0; $total_rec=0; $total_delivered=0; $total_undelivered=0; $total_messages=0; $num_outbound_msg=0; $num_inbound_msg=0; #### Get the message data for a given period In this section of the code we get the message data to calculate usage and pricing using the dateSentAfter and dateSentBefore parameters to establish a window for the results. Once we get the message data, we then add each message to the $row array and increment the status counters depending on the message status. php // Can filter message by whatever parameters you need. This example is any message sent after January 1, 2022. $messages = $client->messages->read([ dateSentAfter => 2022-01-01, dateSentBefore => 2022-04-29, ]); // Write rows foreach ($messages as $message) { $row = array( $message->from, $message->to, $message->dateSent->format(Y-m-d H:i:s), $message->sid, $message->price, $message->direction, $message->status, ); $total_cost += $message->price; if ($message->status == sent) { $total_sent++; $total_messages++; } else if ($message->status == received) { $total_rec++; $total_messages++; } else if ($message->status == failed || $message->status == undelivered) { $total_undelivered++; $total_messages++; } else if ($message->status == delivered) { $total_delivered++; $total_messages++; } // Insert rows into CSV fputcsv($fp, $row); echo .implode(,, $row)..\n; } #### Prepare all data and print the results Once all messages have been parsed, we are ready to prepare the variables that will help make the final result more readable, such as the number of outbound messages as well as inbound. We push the $row array to our CSV. We also get the total number of messages for this period, and sum up the cost of the traffic, turning it into currency from a float. Finally, we print results using the data we have gathered from all of the messages to the terminal, showing message counts, and pricing. php $num_outbound_msg=$total_sent+$total_delivered+$total_undelivered; $num_inbound_msg=$total_rec; $formatted_cost=new NumberFormatter(en_US,NumberFormatter::CURRENCY); $formatted_cost->setTextAttribute( $formatted_cost::CURRENCY_CODE, USD ); $formatted_cost->setAttribute( $formatted_cost::FRACTION_DIGITS, 2 ); $numberString = $formatted_cost->format( $total_cost ); print There were . $total_messages . total messages during your selected date range.\n; print The total cost of messages in your selected date range is approximately . $numberString . USD.\n; print There were . $total_delivered . delivered messages and . $total_undelivered . undelivered messages.\n; print There were . $num_inbound_msg . inbound messages and . $num_outbound_msg . outbound messages.\n; // close file fclose($fp); ## Java ### What do I need to run this code? For the following code to work, you will need to have a Maven project, The Java Wrapper Library and a Signalwire account. Read about how to get started with the Java Wrapper API [here](https://github.com/signalwire-community/compatibility-api-java) Read on how to create a Maven project with Intellij [here](https://www.jetbrains.com/help/idea/delegate-build-and-run-actions-to-maven.html#maven_reimport) ** How to get API Credentials ** The API also requires that you authenticate yourself using your Project ID, API Token, and Space URL. If you do not know where to find these values, check out our guide [here](/platform/dashboard/getting-started/navigating-your-space#api)! ### How to Run Snippet? Assuming youve named your script MessagePriceSummary.java you would need to do the following to run the javac MessagePriceSummary.java then java MessageFromNumber.java. ### Code Walkthrough We also need to instantiate the SignalWire client using the project ID, auth token, and Space URL java public static SignalWireClient client() { return new SignalWireClient(YOUR-PROJECT-ID, YOUR-API-TOKEN, YOUR-SPACE-NAME); } In the main method we need to get our messages the client().message().getMessages().messages method to populate messages from your SignalWire Space. java List messages = client().message().getMessages().messages; Create a variable to store the result of delivered, sent, undelivered, received and initialize all as zero. java int delivered = 0; int undelivered = 0; int sent = 0; int received = 0; double price = 0d; Loop through the result of the messages from the Signalwire API and then append them into the dataLines array that would be used to populate the CSV. As we loop through each item from the API result, We increment the status variable by 1 if its equal to the matching status in our if statement. java for (Message message : messages) { dataLines.add(new String[]{message.from, message.to, message.date_created, message.to, message.sid}); if (message.price != null) { price += Double.parseDouble(message.price); } switch (message.status) { case sent: sent += 1; break; case delivered: delivered += 1; break; case undelivered: undelivered += 1; break; case received: received += 1; break; default: System.out.println(Something went wrong); } } Now that we have the values for undelivered, delivered, sent, received we would print it out to the console for display java String totalMessage = String.format(You sent %d total messages on your space, messages.size()); String priceSummary = String.format(The total cost of messages in your selected date range is approximately %,.2f USD, price); String messageStatus = String.format(There were %d delivered messages and %d undelivered messages., delivered, undelivered); String messageRecipient = String.format(There were %d inbound messages and %d outbound messages., received, sent); System.out.println(totalMessage); System.out.println(priceSummary); System.out.println(messageStatus); System.out.println(messageRecipient); After displaying the summary as show above, we can then call the createAndPopulateCSV() method that then generates the CSV. java try { createAndPopulateCSV(); } catch (IOException ioException) { ioException.printStackTrace(); } Full java code: java import io.github.olajhidey.SignalWireClient; import io.github.olajhidey.model.message.Message; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class MessageSummary { public static List dataLines = new ArrayList<>(); public static SignalWireClient client() { return new SignalWireClient(YOUR-PROJECT-ID, YOUR-API-TOKEN, YOUR-SPACE-NAME); } public static void main(String[] args) { List messages = client().message().getMessages().messages; int delivered = 0; int undelivered = 0; int sent = 0; int received = 0; double price = 0d; dataLines.add(new String[]{From, To, Date, Status, MessageSID}); for (Message message : messages) { dataLines.add(new String[]{message.from, message.to, message.date_created, message.to, message.sid}); if (message.price != null) { price += Double.parseDouble(message.price); } switch (message.status) { case sent: sent += 1; break; case delivered: delivered += 1; break; case undelivered: undelivered += 1; break; case received: received += 1; break; default: System.out.println(Something went wrong); } } String totalMessage = String.format(You sent %d total messages on your space, messages.size()); String priceSummary = String.format(The total cost of messages in your selected date range is approximately %,.2f USD, price); String messageStatus = String.format(There were %d delivered messages and %d undelivered messages., delivered, undelivered); String messageRecipient = String.format(There were %d inbound messages and %d outbound messages., received, sent); System.out.println(totalMessage); System.out.println(priceSummary); System.out.println(messageStatus); System.out.println(messageRecipient); try { createAndPopulateCSV(); } catch (IOException ioException) { ioException.printStackTrace(); } } public static String convertToCsv(String[] data) { return Stream.of(data) .map(MessagesList::escapeSpecialCharacters) .collect(Collectors.joining(,)); } public static void createAndPopulateCSV() throws IOException { // Auto-generate the name of the file String filename = message_result + System.currentTimeMillis(); // Get the absolute path to the folder you would like to create in the project directory File file = new File(Paths.get(csv).toAbsolutePath().toUri()); // if file doesnt exist. create a new folder if (!file.exists()) { boolean isFolder = file.mkdir(); if (isFolder) { System.out.println(New folder created!); } else { System.out.println(Couldn\t create folder); } } // create new csv file with the autogenerated name File csvOutputFile = new File(Paths.get(csv).toAbsolutePath() + \\ + filename); try (PrintWriter printWriter = new PrintWriter(csvOutputFile)) { dataLines.stream() .map(MessageSummary::convertToCsv) .forEach(printWriter::println); // Write item into the CSV file System.out.println(Write operation done successfully!); } } public static String escapeSpecialCharacters(String data) { String escapeData = data.replace(\\R, ); if (data.contains(,) || data.contains(\)) { data = data.replace(\, \\); escapeData = \ + data + \; } return escapeData; } } ## Wrap up Your SignalWire Space allows you to get a good picture of your messaging costs already, but in case you need more information on any given period, these code snippets should help you get all the information you need! ## Sign Up Here If you would like to test this example out, [create a SignalWire account and Space](https://m.signalwire.com/signups/new?s=1). Please feel free to reach out to us on our [Community Slack](https://signalwire.community/) or create a Support ticket if you need guidance!