822

September 16th, 2024 × #javascript#hardware#hackweek

Receipt Printer with JavaScript

Wes explains how he built a receipt printer with JS during Hack Week at Sentry, including connecting it, encoding printer commands, taking screenshots to print complex layouts when alerts come in from Sentry.

or
Topic 0 00:00

Transcript

Scott Tolinski

Welcome to Syntax. On this Monday, hasty treat, we're gonna be talking all about Wes Hack Week project, which Wes a receipt printer with JavaScript.

Topic 1 00:10

Building a receipt printer with JS

Scott Tolinski

This is one of the coolest things he JS posting about it on social. I'm really stoked to get into the nitty gritty about what it takes to build a receipt printer with JavaScript and why you might wanna do that, maybe some of the protocols that were you know, just interesting things that Wes learned. My name is Scott Tolinski. I'm a developer from Denver. And with me, as always, is Wes Bos, the receipt printing man. What's up, dude?

Wes Bos

Hey. It was a really fun project, so I'm excited to people have been ESLint. Like, I can't wait for the syntax rundown on all the different details on it. Yeah. It is Hack Week at Sentry, and, Sentry is the perfect tool

Scott Tolinski

to find all of your errors, maybe print them out as a receipt and have them available for you to see. It's so fun.

Scott Tolinski

Sentry is just one of those tools, again, that if your application has errors, which you know it's going to, it allows you to fix those errors faster and easier and with way less stress than you could without it. So it's an essential tool in my tool belt, and it was long before this podcast was presented by Sentry. So thank you to Sentry.

Topic 2 01:10

Hack week at Sentry

Scott Tolinski

So Hack Week at Sentry. It Yeah. This is our 2nd Hack Week at Sentry. The first one, we had some pretty neat projects. Wes worked on a hardware project again. I worked on a multiplayer text editor. But Hack Week, if you don't know it, at at companies JS often you get a time to just work on some cool stuff. And maybe it's related to, Sentry or your business. Maybe it's just something off the warp. But it should be something interesting and exciting and maybe stimulating you to learn Node things. So, Wes, do you wanna tell us a little bit about your project, why you made it, what's the deal?

Wes Bos

Yeah. Okay. So what I did was I got a receipt printer, which is what you see at, like, a restaurant in a kitchen, or you go to a coffee shop and you buy something and it goes, and then it prints out the receipt and they hand it to you and you throw it in the garbage. Right? I have always been very curious about how those things work, especially I can remember exactly. I got a receipt from Toys R Us when I was a kid, and the r in Toys R Us was backwards.

Topic 3 01:46

Got curious about how receipt printers work

Wes Bos

And I always remember thinking, like, how did they get a backwards r? And now I realize it's probably like a Cyrillic character that they threw in there, but I've always been curious about how these receipt printers work. So what I did was I I got Node, and I decided I'm going to hook it up to Sanity so that when a SENTRI issue comes in, it will just automatically print it. And I'll talk about how I got there, throughout this episode.

Topic 4 02:40

Hooked printer to network and sent data

Scott Tolinski

So made you pick that as a a thing to focus on given that the parameters at Hack Week are are really broad? Like, what made you I know you said you're curious about receipt printers, but, like, comes to Hack Week, and you're like, I'm a do receipt printers? I

Wes Bos

I always like poking around with hardware. You know? And I always like like, I've done the drone in the past.

Wes Bos

I last year, I did the this on air sign that's behind me.

Wes Bos

And I've always thought it was kinda interesting to be able to control stuff that is in our everyday life. Like, my goal is to one day just do a vending machine controlled with JavaScript. And, it seems kind of silly to do it with JavaScript, but the beauty of that is you realize, oh, a lot of these things that are out there are all based on standards. And if you can send data via whatever programming language, you can control these types of things. So I thought, alright. I'm gonna try that out. The printers, I've done quite a bit of work with the label printers in the past. We did an episode on that on I have the the wrist the gun that you can scan the label, and and it will automatically print it. We did a whole show on that, but I've never actually touched the receipt printers.

Wes Bos

So these printers are all pretty much the same, meaning that they all communicate on a standard called Wes Bos.

Topic 5 03:55

Printers use ESC/POS communication standard

Wes Bos

And this is a standard in the point of sale community or or industry where you can if your receipt printer breaks, you can just go grab another one and plug it into your cash register, and it will just start to work because your cash register or your point of sale will just send the same kind of data to your printer, and it will print the same kind of receipt every single time. Right? They all operate on either 80 millimeter or, I think, it's 60 millimeter thermal paper, which I've since learned is very bad for you.

Wes Bos

I had probably 20,000 people say, link me to a study that this contains BPA.

Wes Bos

Really? And these poor cashiers that are grabbing them all day long. Yeah. I used to work at Target. I'm all about that.

Wes Bos

Yeah. So, apparently, there's BPA in them, and, you can buy BPA free paper. So I got 10 of these rolls, and I I printed, like, all day long for, like, a whole week, and I only got through a roll and a half. So it's it's cheap stuff. And the way that it works is that there's no ink in these printers. It simply just gives heat. And if you were to hit it with a lighter, the whole receipt would would go black because it's just where the heat is on the the thermal paper.

Wes Bos

So you have the printer. You have your your thermal paper in it. And then how you communicate with the printers is really what I was is was interested in how that works. So these printers can be hooked up via Bluetooth.

Wes Bos

They can be hooked up via USB. They can be hooked up via serial port. Like, it literally came with a serial port, or it can be hooked up, to the network. A lot of them will have network cards in them, and they'll just, like, run their own little print server on it. So I've seen a lot of people in the past hook up to them with web Bluetooth or web USB, which is really interesting, but I wanted to do mine primarily server side. So both of those things were not great even though there there are packages in Node for working with Bluetooth and USB. So I just hooked mine up to a hardwired Ethernet connection here, and you press a series of buttons, and it prints off the IP address of the printer as well as a port. So right away, I got a local IP address and a port, and then you simply just create a TCP socket.

Topic 6 06:25

Built TCP socket in Node.js to connect

Wes Bos

In my case, I just use Node. Js. I imported socket from the net package. Wow. I did try use WebSockets, but that is not entirely a TCP implementation. You can't do TCP from the browser.

Wes Bos

So I I did it all via Node. Wow.

Wes Bos

So you create a socket.

Wes Bos

You connect to it via an IP address and a port, or you can connect to it via USB or whatever.

Wes Bos

And then you what you do is you start to send that socket data, and that data needs to be formatted in the ESC POS format, which means that there are a number of preset commands for incrementing the font size, bolding the font size, inverting, all of the things that you're used to seeing on a receipt. And that's why if you look at a receipt, generally, these receipts all kind of look the same Mhmm. Because there is there's only a limited API for doing things like tables and and layout and and whatnot.

Wes Bos

There is a really good package from Niles Lanher, and he's written a whole bunch of packages for working with this type of stuff because I believe he works for or has a company that does point of sale software, you know, like an iPad that you can you can tip on and it prints a receipt.

Topic 7 07:25

Found a JS library to encode printer commands

Wes Bos

So he has this package called Wes Bos encoder.

Wes Bos

And what this will do is it will take you from literally sending hexadecimal bits to the printer, which is I started with that. I I did a hello world, and it will give you a nice JavaScript API for saying, like, you you create a new encoder, and you can do Scott image and do dot text and dot invert true, and it'll give you all of the an API for doing this type of stuff that is fairly sane.

Wes Bos

Once that's encoded, you simply just take your Scott, and you say socket dot I believe it it's Scott send.

Wes Bos

You you send it that thing and, like, the first time I tried it. Like, I literally just coded something, and I tried socket dot send, and it printed the very first time. How many times does that work? Just like, never. Never. Yeah. Absolutely never.

Wes Bos

I know. There's always something where you click the button. You're like, alright. Go. And then you get the console there, and you're like, alright. Yeah. Yeah. The kind of funny thing about the socket was I actually ran into some issues because I ended up building a React JS or Next JS server components application because I then took it and allowed people to send photos of themselves. So I hooked it up to get user media with the webcam. So some you go to the URL, you click a photo, and it printed out on my desk. And I was having thousands of people sending me photos, and it was printing off my desk. My whole desk was full of paper. It was really exciting. And then I also allowed people just to type text.

Topic 8 08:37

First print attempt just worked

Scott Tolinski

That was gutsy, though. That I will say. The photos thing, very gutsy.

Wes Bos

The photos thing was very gutsy, and I did not have a single bad thing come through. Can you, like, I I probably had maybe 2, 3000 images come through, and not a single person sent anything bad. And then the That's crazy.

Wes Bos

Yeah.

Wes Bos

I I don't know.

Wes Bos

It's hard to say why.

Wes Bos

I turned it off before it got out of my circles. Okay. That's why. Yeah. Because the the tweet did get pretty popular in, like, a couple hours in. Like, once the anime avatars start, getting ahold of it, then I had I Scott it down before it got crazy. But I did with the text one.

Wes Bos

The text one, I ran it through a transformers JS model that would detect toxic comments, and it was so good. Like, you could you could misspell I kinda felt bad, like, typing stuff that was toxic because I was like, like, is someone gonna know that I'm typing these bad words? You know? But I needed to test it, and it would catch almost everything.

Wes Bos

Like, misspelled bad words, negative talk, all kinds of stuff, and it filtered that all out. And I didn't I I only saw one thing that someone got through. They did ASCII pair of mammaries, which did not get caught.

Scott Tolinski

For some reason, using the word mammaries is so much worse than any other word you could have used there.

Wes Bos

So the that socket, Scott that socket let me come back to explain that socket JS there can only be 1 socket connection to this thing at once. So what I had to do is I would I would take in the incoming connections, and I I surfaced it via Cloudflare Wes or Cloudflare tunnels.

Wes Bos

And, basically, people are like, why am I getting Next. Js dev server errors when I'm visiting the website? I'm like, because I'm literally working on it right now Yeah. And you're visiting my computer via thing. But, like, I ran Next. Js dev server all night, and it it had thousands and thousands of people visit it. And it it held up just fine. But one thing that did not hell hold up fine was the socket.

Wes Bos

When you connect to a socket via a server component that is meant to be called from the client side, you know, like like RPC, and just a socket that's meant to be called via this via a server function.

Wes Bos

It was trying to create 2 sockets, and I went deep. And Next. Js does something weird with 2 different webpack bundles for React Vercel Components. So that was a bit of an issue. And you also hit that with databases as well where you have multiple connections to a database, and you can only do 1 connection. And that's where you get, like, connection pooling coming in. So I thought that was kind of an interesting learning point of, oh, I can't just ESLint up multiple sockets. I wasn't. But because the way Next. Js works is I was it was trying to make 2 connections, and that was a bit of an issue. So once I had hundreds of people put printing off images and and texts, I said, alright. I'm pretty comfortable with how all of this works. I wanna actually do what I set out to do, which is make a receipt that shows my Sanity issue. So I thought the formatting on Wes POS is not very good.

Wes Bos

It's very limited, but what is not limited is HTML and CSS.

Topic 9 12:45

Used HTML/CSS for receipt layout

Wes Bos

So what I did is I formatted the entire receipt in HTML and CSS, and I use Playwright to visit the URL, take a screenshot, convert it to an image. And then I took that image, and I sent it to the printer, which is something you're allowed to do. So I basically sidestepped the entire Wes POS format except for the part where you can send images to. Totally. And it it worked really well. Like, I know and everyone can see this, but I, like, did a pretty nifty little layout of my Sanity issue Wes I I have the ID of the error. I have the actual error itself. I have the cause of the error, like, which page is it on. I have I built a little graph with Flexbox that shows how often it's happened in the last 24 hours 30 hours, bunch of metadata, which browsers it's happening on, what devices it's happening on, which OS it's happening on. And I I feel like I did a pretty good job laying it out, and it it it looks good. Like, if I were to get that if I was a poor dev and somebody slapped this on my desk, hey.

Wes Bos

Work on this issue.

Wes Bos

I'd be like, wow. This has enough information for me to make actionable change. You know what that could use, Wes? Here's my only

Scott Tolinski

my only suggestion.

Scott Tolinski

You could put a QR code on there, scan that baby, and have it take you to the actual century issue so that way you could Yeah. Like, get get the rest of the information or I was thinking that is resolved. That's a great idea. And

Wes Bos

the printers have QR codes and data matrixes

Scott Tolinski

built in to the printer. Yeah. So I wouldn't even have to use a third party package. Yeah. And let me tell you, I I've done done some QR code work recently, and it's just a simple. Even if you wanted to use a package. It's just a simple canvas,

Wes Bos

Node function call to generate a QR code. So Yeah. It it works well. I've done I did it on my, like, receipt scanning or, label scanning thing in the past.

Wes Bos

I did have to use the Node canvas package because Oh, no. There's no Yeah.

Wes Bos

There's no canvas on the server.

Wes Bos

But it it worked well aside for some Node JIP install issues that I I hit.

Wes Bos

Printing images, the package that I used has 4 different dithering algorithms. So if you try to print an image straight away, it will just do black or white, and it doesn't look very good.

Wes Bos

But there's algorithms that will dither the images, meaning that they will take away and and add images and try to make it, like, faded, and it does a really good job at printing images. I was pretty pretty impressed.

Topic 10 15:27

Took screenshot and printed as image

Wes Bos

Once I had Playwright taking a screenshot and sending it to the printer, the last step was I made a API route that I went into Sentry. I created a new app called Sentry Vercel Printer, and then I set it up so that we have webhooks on new issues or on issues that have been updated or maybe you resolve them and they come back.

Wes Bos

And whenever that issue happened, it would ping the webhook, and then I would be able to get the information about that specific issue as well as its status, etcetera.

Topic 11 15:53

Set up webhook to get data on new Sentry issues

Wes Bos

And, I could just basically send that to the printer, and it would bring it right on up. And that was the end of of my week of working with a thermal printer. Wow. So

Scott Tolinski

all in all, would you say that, like, the Hack Week, project Vercel benefited you in the long term in any sort of way, or was it just like a curiosity solving thing?

Topic 12 16:30

Learned about sockets, APIs, surfacing local servers

Wes Bos

Yeah. So a lot of people were like, but but why? You know? And I I can't tell you how much interesting stuff I learned. I learned a lot about socket connection, issues that could pop up. I learned a lot about how, like, real stuff works.

Wes Bos

I learned a lot about surfacing my local computer to to the Internet without giving my IP address out to to everybody.

Wes Bos

I learned I learned a lot about the the Sentry API and and the Webhook API and and how that all works. So I I think that sometimes people see these projects as silly and stupid, but when you're having fun and I'll tell you. I've had tweets from probably 6 or 7 people that have already bought a thermal printer and are are doing the exact same thing because it is so fun, and it really reenergizes your, your appetite for building this type of stuff when you can do something that's not your standard, like, form data updated database. It's it's kinda fun. And and, like, even somebody at Sanity, I think it was the the Seattle office, already ordered

Scott Tolinski

a thermal printer. Just to get up and running? They're gonna build, like, a, like, an internal Instagram where you can, like, send photos from office to office. That's so cool. It's where you can, like, send photos from office to office. That's so cool. See, look. And and that's the whole thing that's the whole thing about Hack Week is that, like, the the projects don't end up having to be, like, stuff that ends up in the product at the end of the day. And sometimes they are. Sometimes they're not. Sometimes they end up being super useful. Like, oh, we'll talk next week about the project that c and I CJ and I put together. That is very useful. Yeah. We'll get a lot of use out of, but we also learned a lot. But at the end of the day, you know, Hack Week is about exploring curiosity.

Scott Tolinski

And the results of that can be all kinds of things that you maybe didn't even set out to do. But, man, if if your company doesn't have a Hack Week or maybe you're even, like, a small team or something like that, it's kind of a cool idea if you can find a week or even, you know, 4 days of a week to crunch on some just experimental anything and set out and try to create a a project over that amount of time. It it was for me too very personally renewing in terms of energetic and and, like, we were able to accomplish so much, and I learned so many different new techniques. And, yeah, it it's really quite quite the experience.

Wes Bos

Yeah. I will recommend it to anybody. If you see especially these thermal printers, they're about $100, but you can often find them on, like, a marketplace or a thrift store.

Wes Bos

The one thing I was trying to buy a cash drawer with one of them as well because part of the ESC POS standard is that you can send a beep, and that beep essentially just sends a a signal to something.

Wes Bos

And that something can be a cash drawer and, it opens on up Yeah. Which is always fun. That's hilarious. So I highly recommend checking it out. I'll post the link to my GitHub with all the thermal printer code. I think you'll be surprised at how how relatively simple it JS, even though I did, like, quite a bit of screenshotting and whatnot. But the actual connecting to the printer and sending data to it, I I don't know, maybe maybe 30, 40 lines of code.

Scott Tolinski

Amazing. And super cool. So thank you so much for sharing that, Wes. I I always stoked to see what you're gonna come up with. Whenever we start talking Hack Week, you're like, I think I'm gonna do hardware,

Wes Bos

then just know it's going to be something wild. So it's always fun. Right on. Alright. Thanks everybody so much for tuning in. We will catch you on Wednesday.

Wes Bos

Peace.

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window