Send + receive faxes using Twilio’s Fax API and C#

Danny Cabrera
Aug 22, 2019 · 5 min read

It is not something I do often but every now and then I need to send or receive a fax. I generally search services online and look at different mobile apps. On occasion I have also opted to visit the nearest UPS or FedEx store. The problem I find with online services is that most require a subscription, free ones add their information on the cover page and most mobile apps require credits in the form of in-app purchases. There’s definitely nothing wrong with either of these avenues but I thought how cool it would be to simply write my own. I remembered Twilio has a fax API that is still in beta and decided to code my own. In this post I’ll describe how to build a simple console app to send/receive faxes. Please note this sample is just a proof of concept and doesn’t take security measures into account.

Goal

Send/receive faxes using C# console app.

Requirements

Twilio account & a fax capable phone number

Twilio Account Setup

The first step is to create a Twilio account if you don’t already have one. Once you have your account the next step is to purchase a fax capable phone number. Phone numbers run a $1.00 a month and you’ll pay $0.01/page
(First 100 pages are free) + SIP Trunking minutes for transmission. You can find pricing here.

When searching for a number to buy, make sure to check the “Fax” capability option.

Searching for a fax capable number.
Example of a fax capable number returned in search.

Creating Console App

The next step is to create our console app. The goal here is to create an app that allows us to send faxes and at the same time receive callbacks from Twilio informing us of Statuses and Incoming faxes.

Let’s start by creating a new Console App Project named FaxApp.

Once the project is created let’s add two nuget packages:

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost -Version 5.2.7Install-Package Twilio -Version 5.31.3

In our FaxApp project, let’s also add a reference System.Web assembly.

Next let’s create a folder called FaxApp in C:\Temp and two folders within it, Inbound and Outbound. We’ll use the Outbound folder for PDF files we will fax out and Inbound will store received faxes.

Sending/Receiving a fax

Now that we configured the project lets start coding.

Let’s start by adding a new class named Startup.cs. This class will configure our Owin self host API which will route requests to the CallbackController we’ll create next.

Startup.cs

Next let’s create CallbackController.cs which will contain the POST and GET webhook methods Twilio will call when a fax comes in or a fax status changes.

  • Status — called when a fax status changes
  • GetFile — called when Twilio retrieves PDF we are faxing out.
  • Sent — called when a fax is incoming, controller then lets Twilio know what action to perform, in this case calling /faxapp/callback/received.
  • Received — called when a fax is received, we’ll download the received PDF from Twilio and store it in the Inbound folder.
CallbackController.cs

Next let’s create Util.cs. This class contains method DownloadFile which we’ll use to download received PDF from Twilio and write it to the Inbound folder.

Util.cs (DownloadFile)

Lastly let’s add some code to our Program.cs class created along with the console app.

Let’s dive into what is going on within Program.cs.

First thing we do here is startup our self-hosted Owin API by initializing:

_app = WebApp.Start<Startup>(url: “http://192.168.1.100:9000/");

WebApp will listen on our local IP 192.168.1.100, Port 9000. Please change the IP and Port to your match your local device. This will start our API which Twilio will call. In order for Twilio to call our API, log into your account, navigate to your phone numbers and manage the Fax capable one you purchased.

  1. Let’s tell Twilio to accept incoming “Faxes”.
  2. Setup a webhook url so Twilio can let us know a fax is coming in.
  3. Setup a url so Twilio can send us fax status changes.

For this demo I opened up port 9000 on my Unifi Gateway firewall and forwarded it to local IP 192.168.1.100. In my case I configured my dynamic dns hostname in the url on #2 and #3 above. You may also use your external IP address. Reason for this step is Twilio needs to be able to talk to your API. Twilio does provide an example that uses ngrok so may check that out.

As a side note, I also had to open port 9000 on my Windows firewall to allow inbound traffic.

Once you have your external url add it to variable myRemoteAddress on Program.cs:

var myRemoteAddress = “http://myExternalIPOrUrl:9000/faxapp/callback";

When sending a fax, myRemoteAddress is passed to Twilio so they can get the PDF we are faxing out and provide status callbacks.

Before sending a fax log into your Twilio account, locate your AccountSid and AuthToken and add them to Program.cs here:

TwilioClient.Init(“TwilioAccountSid”, “TwilioAuthToken”);

Running Console App

When starting FaxApp the Owin API will start listening for requests and console will await user input.

Sending a fax:

Simply type sendfax command, you’ll be prompted for the number you’d like to fax followed by the PDF file you’ll be sending (PDF will be stored in C:\Temp\FaxApp\Outbound so app just needs file name ex. Sample.pdf).

When fax is sent it will get queued and console will output the fax sid and status. When Twilio sends any status updates the console will display it.

Receiving a fax:

Provide your fax number to the sending party and simply wait for console to start displaying status updates. When the fax is received FaxApp will download the PDF and display the path to the file it created in C:\Temp\FaxApp\Inbound. For testing I was able to send myself a fax and test both outbound + inbound.

Conclusion

Hope this sample is useful to those seeking an alternate fax solution they can code and modify to their liking. Happy Coding!

Links

Code is available on GitHub: https://github.com/dannycabrera/FaxApp

Twilio:
Quick start guide: https://www.twilio.com/docs/fax/quickstart
Helper Libraries: https://www.twilio.com/docs/libraries
Reference Docs: https://www.twilio.com/docs/fax
Pricing: https://www.twilio.com/fax/pricing

Danny Cabrera

Written by

Principal Software Engineer at Command Health https://github.com/dannycabrera

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade