My Textable Cat Printer
Tags: twilio, showdev
Published: 2021-08-11 04:39:08

I was scrolling on twitter one afternoon and saw that xssfox had a Bluetooth Thermal Cat Printer. I have had an idea that required a thermal printer for a while now and this looked like a really good printer for what I wanted to do, so I ordered one.

{% twitter 1420254881613451272 %}

The original idea I had was to set up a thermal printer so you could message it a picture, have it print off and stick it in a guest book, like you might do with a polaroid at a wedding. But It doesn't look like I will be going to a wedding any time soon. So instead, to allow people to interact with it remotely, I decided to give it a phone number and let people send messages that would print out on my desk.

To contact it, message `cat:[message to print]` to one of the below numbers to have it printed.
**Aus:** +61 480 029 995
**US:** +1 520 521 0228

# Giving The Cat Printer A Number

To be able to give the cat printer a number, first I had to get it to print. I pulled out a raspberry pi I had from the time I had my apartment lights controlled using amazon dash buttons. xssfox had some code that allowed you to send messages and images to be printed via HTTP requests. After getting that running on my pi and debugging some differences between how python handles bytes between Windows and Linux, I was able to send my first messages to print!

The python code I am using is available at https://gist.github.com/mpomery/6514e521d3d03abce697409609978ede

{% twitter 1420599852061237248 %}

Once I had it printing, I went into my Twilio console and started adding some functions to my textable light project. I created a new function that would look at the incoming message for the prefix `cat:` and redirect the message to the cat printer. Later I went back and made my light require the prefix `light:` and an error message if neither of the prefixes were present.

The function looks like this:
```javascript
exports.handler = function(context, event, callback) {
  let twiml = new Twilio.twiml.MessagingResponse();
  
  if (event.Body.toLowerCase().startsWith("cat:"))
    twiml.redirect("/cat_printer");
  else if (event.Body.toLowerCase().startsWith("light:"))
    twiml.redirect("/textable_light");
  else
    twiml.message(`"light:[colour]" to add a colour to the light
"cat:[text]" to print on the cat printer`);
  
  return callback(null, twiml);
};
```
 
I then set up a second function `cat_printer` to format the message to be sent to the printer. It takes the incoming message, removes the `cat:` prefix, redacts part of the number it was received from and formats it with a timestamp for printing. Then it makes a call to the web server running on my raspberry pi (which was made available to the internet using ngrok) to print it. Once that request has been made, the response from the printer gets sent back to the number who texted it.

```javascript
const axios = require('axios');
 
exports.handler = function(context, event, callback) {
  let twiml = new Twilio.twiml.MessagingResponse();
  
  let incomingMessage = event.Body;
  if (incomingMessage.toLowerCase().startsWith("cat:"))
    incomingMessage = incomingMessage.substr(4).trim();
  
  let from = event.From;
  from = from.substr(0,3) + "*".repeat(from.length-6) + from.substr(from.length-3);
  
  let now = new Date();
  
  let printMessage = now.toLocaleString('en-GB', { timeZone: 'Australia/Sydney' }) + "\r\nFrom: " + from + "\r\n" + incomingMessage;
  
  console.log(printMessage)
  
  axios.post(context.catURL + '?text=' + encodeURIComponent(printMessage))
    .then((response) => {
      twiml.message(`${response.data}`);
      return callback(null, twiml);
    })
    .catch((error) => {
      twiml.message(`You sent a message with special characters or the cat printer is offline.`);
      console.error(error);
      return callback(null, twiml);
    });
};
```

# Getting People To Message It

Once I had it working I started telling people about it. Some of my friends had already seen my textable light, so the idea of sending a text message to something on my desk wasn't new to them. I was initially cryptic about what I had made, but once people knew what it was they started messaging it!

{% twitter 1420892406476468228 %}

Some of my friends made me regret telling them about the cat printer:
{% twitter 1421019519485571072 %}

I streamed it briefly so people could see what they sent print in real time, including this really long message:
{% twitch https://www.twitch.tv/mitchpommers/clip/PatientInexpensivePigTakeNRG-W0ojMkY5ohNpk5ha %}

Then I started to see several people sending it messages internationally, so I purchased a second Twilio number so I could respond to them:
{% twitter 1424959545302937601 %}

And then the TwilioDev twitter account tweeted it, expediting this blog post:
{% twitter 1425255647017324546 %}

Now that I have it built and it has a semi-permanent position on my desk, I need to make a better way to keep all of my projects displayed on my desk. I would really like to make them all visible on the internet permanently. I have ideas on how I could achieve this, but don't have access to what I need to make it possible or the space to do it at the moment.

And if you are considering making something similar yourself using Twilio Programmable Messaging, you can [get $10 when you upgrade using this link](www.twilio.com/referral/QqpNkR).