 Thank you so much for coming. My name is Greg, and if you couldn't tell by the video, I'm giving the talk on how I taught my dog to text selfies. So first off, I just want to say it's a huge honor to be here. The first time I ever gave a talk at a tech conference was at Mountain West Ruby Conference about three and a half years ago. I spoke on developers and depression. And I had only been coding Ruby for about a year, and the community was so amazing and has continued to be as I've gone to other Ruby conferences. And I now serve on the developer evangelism team for a company called Twilio and have the privilege of going to a lot of conferences for a lot of different languages, and the Ruby community still always very much feels like home. So I've had the privilege of speaking at RailsConf before. This is my first time at RubyConf, and it really is kind of a bit of a dream to be here. So thank you all, and if any of the organizers are here, I much appreciate having me up here. So I'm Greg, I now live in New York. My wife, daughter, and I just moved to Brooklyn about four months ago after 11 years in Chicago, and we're absolutely loving it. We just wanted to try something new while our daughter, she'll turn two on Monday while she was young. We didn't have to worry about school too much and stuff. And so that's pretty awesome. This is not our entire family, though, as you may have guessed from the text or from the title. About a year before Emma came along, we got Kyra. She was 12, this is the day we brought her home. She was about 12 weeks old when we got her. She's a rescue. We're not really sure what she is. We think she might be part Shiba Inu. There's this other dog called an Australian Kelpie. We're not really sure, but she's really smart. She's really, really smart. And she has a stubbornness that often comes along with that. And so very early on, we realized that we were going to have to put some effort in there if we wanted to like her, which is still a challenge sometimes. But there's this awesome book that we eventually found. It's called Don't Shoot the Dog. And it's written by a woman who used to train dolphins at SeaWorld and then has done a whole bunch of other animal training. The crazy thing about reading this book is you get a few chapters into it. It's not actually about pet training. It's about behavioral conditioning. And so all the tricks that they teach you also, you can't really read it here, but they also work on small kids and co-workers and whatnot. And it's just all about positive reinforcement. Because it turns out yelling at your dog just doesn't work. The trick is that you find something in their behavior that's worth complimenting and rewarding and you reward it. And then you just kind of keep doing that and moving the goalpost. So being the rebellious type, reading this book, reading the title, one of the first things I did was shoot my dog and teach her how to do that. And then one day we were laying in bed and we had this floor lamp next to our bed. It's from Ikea and it's got a little switch on it that you just stomp on in order to turn the light on and off. And I'm like laying in bed one night and I'm done reading and I look at this lamp and I'm like, I don't want to get out of bed to go turn that off. I shouldn't have to get out of bed to turn that off. I have a dog. And so we start setting down this path of trying to teach Kyra how to turn a light on and off. And we would just take her over there and we would at first just take her paw and we would just grab it and then place it on the switch and if she just made contact, we just reward her. We give her a treat. And then we would do that and then once she got to the point where she could walk over and she could push it and actually make contact, then we start pushing down her paw and it would click. We'd say, you know, we preface all this by saying light and then we give her a treat. And so we ended up getting to the point, it took a couple of weeks, but we got to this point where we could then stand across the room and say, light. And so now I started thinking, I have a dog that can press a button. I wonder what I can do with that. And as I said, I work for Twilio, for those of you who have heard of us before, we're best known for our API that makes it really easy to send and receive text messages and also place and receive phone calls. And for a good chunk of our history, you could only do text messages a couple years ago right around the time Kyra learned how to press a button. We also launched MMS so we could send picture messages. So now I'm like, man, how do we get her to press a button and send me a text message? And I had no idea how to do this because I had never done any hardware hacking. I had taken a single electronics engineering class in college and was terrible at it. I really liked software because of the instant gratification and the whole hardware world just seemed very intimidating to me. I did a little bit of Googling and I discovered this thing called the Arduino UNE. And who here has played with an Arduino before? All right, cool. So about half the room. So the big difference between an Arduino and an Arduino UNE, like the standard Arduino, is that the Arduino UNE is Wi-Fi enabled and then it also has a second processor on it. So it has the two processors. One does all the stuff you think of with an Arduino. The other one runs a stripped-down version of Linux called OpenWRT. And was able to really just using basically the second example in the Getting Started Arduino book, which is how do you press a button? So if you're a player in an Arduino before, the hello world of hardware hacking is blink, like make a light turn on and off. Hello world plus one is do that with a button. All right. And so this is the circuitry required to push a button. It's literally like four pages into the Getting Started guide. And then the way that you would control the Arduino UNE is from the software side as you would SSH into it. And so for the last couple of years, I've been actually about a year and a half now. Mostly using the Arduino UNE, it comes with Python installed. And so I learned just barely enough Python to kind of pull this off. And was able to do the same thing with PHP. And then started playing around with Ruby, which is my first language of choice. And it could barely run Python, barely run PHP. And I could hello world in Ruby. But it just wouldn't hold up with gems. Like you couldn't install gems on it. And then there was all these other limitations that came into it. So I started wondering and started experimenting and wanted to play with the pie. Because as I gave this talk at other conferences, people will come up to me like, well, couldn't you do the same thing with the pie? I'm like, well, I don't know. Well, as it turns out, the Raspberry Pi 3 costs half as much as the Arduino UNE. So the Arduino UNE is about $70. The Raspberry Pi 3 is $35. Additionally, Arduino discontinued the Arduino UNE about a month ago. You can still get it outside of the United States. But you can no longer buy it inside of the United States, except from suppliers who still have inventory left. So for the last few weeks, I've been playing around with the Raspberry Pi. And it is so much better. So much better. And it has just been an absolute joy. So what I wanted to do for the rest of this talk is build this device so that we could let a dog text selfies. And so we're going to look at just the components real quick. And then we're going to write some software, some Ruby code to power this thing. So the first thing we needed is a camera. The Raspberry Pi does have a official branded camera. It costs $40. So it actually costs more than the Pi. And it's pretty small. The cable is pretty small on it, which could be super useful in a lot of applications. What I ended up using is just a standard USB camera, in part because I had one laying around. Only costs $20. The Raspberry Pi 3 has four USB ports on it. And so you just plug it right in. And it just works. Like the drivers on it just work without installing anything else. No matter how many treats we gave her, Kyra never learned to type. So we just needed a big red button that she could press. This thing costs $10. We housed it all in a cigar box. Cigar boxes you can buy for about $2 from your local cigar shop because they're just trashed to them. So once they sell all the cigars, you can just buy the box. And so it makes really beautiful and sturdy enclosures for your hardware hacking projects. This is what the internals look like. And so we have the Pi on the left and then this breakout board. And then if you take a look at the circuit, it is just about as simple. Well, it's exactly as simple. It just looks a little more complicated. But it's the same circuit that we're doing on the YUN. Here's a different view. And basically, we just have a circuit running. And then it runs into the button. When you press the button, it sends a signal to a pen. And it just registers that there's current flowing through that pen. And we'll look at how we read that. And so this is what the internals of this box look like as of this morning. I probably need to figure out how to clean that up a little bit. But we're talking about super, super simple stuff. And in order to make all this hardware work, we just need three steps. So we need to take a picture. We need to upload the picture to the cloud. And then we need to send a text message with that picture. All right, so I thought we'd just write some Ruby and make that work. Sound good? Y'all could flip over to the pie. We were having fun playing with this, getting this up and running earlier. We don't have a monitor here. So I found this is a good way to instill empathy within the audience. Is that I'm staring at this right down here as I type once it comes up. And so we had to increase the font pretty big. So hopefully, y'all in the back can still see it. No luck there? Well, let's see here. Oh, you're absolutely right. All right, very good. All right, cool. Can you, in the back, can you see this okay? You can read it? All right, fantastic. All right, so the very first thing we need to do, so I'm in a directory here, my Ruby's directory, just have a folder called Ruby comp. First thing we need to do is take a picture. So I'm just gonna create a new Ruby script here and we will call this take picture. And this is actually pretty simple. We actually aren't, I mean, we're technically doing it in Ruby. But there is a shell script, not even a shell script, there's just a command you can run in Linux, a little utility from the command line called FS Webcam. And you can just pass FS Webcam a resolution and a file name. And once you do that, I'm just using back ticks here, so I'm having Ruby execute this command. And when I run that, I've got the Webcam right here, it's plugged in to the pie. So I'm gonna run this here, so if the people in this area right here wanna smile, and you can see that it captures the picture and then now we have pick.jpeg that's in here. And if I go to this little, little small for me, so let's try it like this, we'll go to, oh boy, we're gonna have to type this, ruby slash ruby com slash pick.jpeg. There we go, all right, cool. All right, so you can see we have a picture taken from the Webcam of everyone right here. All right, so step one, pretty easy, complete one line of code, really just running a shell command from Ruby. All right, so step two is we need to upload that picture to the cloud. And strictly speaking, this isn't for our particular use case a necessary step. In just a minute, we're gonna open up a tunnel so that we can have direct access, give our Raspberry Pi here a publicly accessible URL. We could do that, but what I wanna do instead is take this picture and put it up to a place that can handle some load and put it up to a place that's not connected to the internet via hotspot and that's not running on a low power computer. All right, and plus there's lots of other use cases for uploading files to the cloud. So we will create a new file called upload picture. And we are gonna use the Dropbox SDK. And you could do this with several different methods. S3 was the one that first came to mind for me, but the API is just pretty terrible and the documentation's pretty terrible. Dropbox has done a fantastic job with their API and with their documentation. It was really easy to get up and running. And if you have a Dropbox account, which I would imagine most of you do, you can just create a app. You go to developers, Dropbox.com slash developers slash app. You'll create a new app and then you can create an access token. Here we go. And we'll create this access token right down here and we'll copy that. And with that access token, we can, here let's put this into a method. So we'll call this upload picture. So we will create a new client and we will pass in an access token that we just copied from our dashboard. By the way, if y'all see me make a mistake, feel free to shout it out. All right. Once we have that client, we'll go ahead and we'll open up that picture and then we can use the client to put the file. We'll give it a name on Dropbox. We'll just give it the same name and we'll pass that file in here. That gives back a response of some information about the file we just uploaded. Inside of that response is a path to the file, like in the Dropbox file system. So we'll grab that path and then if we pass that path into a second API called media, then it will return another hash and inside that hash will be a publicly accessible URL. All right, and then we'll just have our method here. Return that URL. And then just for to see if this works, why don't we output that URL or we'll output that URL by running our method here. Let's see what happens there. All right, cool. So we got a URL back. So we'll take this URL and we'll copy that. I think I'm getting old. Either that or, you know, I just need to bump this up a little more. Oh, there we go. All right, cool. So now we have our file that was just on our Raspberry Pi. We've been able to take it to upload to a cloud. So you can imagine that there's a whole bunch of useful use cases for this, right? Being able to take files that you create on your Pi, putting them up there. Dropbox makes it so incredibly easy. Just a few lines of code, just a few clicks on your dashboard and you can do that. All right, so that was step two. We did step one. We took a picture. Oh, and uploaded it. And then now we need to send that text message. So for that part, we're going to use Twilio. And I came on here and searched for a phone number. So everything you do on the SMS and on the phone side is going to start with a Twilio phone number. So these cost $1 a month. And I'm going to come on here and I'm going to buy a phone number in the 513 area code here. So it'll be a local number. I don't even know if long distance is really a thing anymore. I feel like that's one of those things my daughter is never going to really understand. But okay, so I just purchased this number. If y'all want to pull out your phones, this is going to be a lot more fun if it's interactive. So in just a minute, I'm going to have you text your name to this phone number that we just purchased here, all right? And what's going to happen when you send that text is that Twilio is going to make an HTTP request to whatever URL I put into this field right here. So this is our message webhook. And so what I'm going to do is just write a small Sinatra app. And that Sinatra app is going to handle that HTTP request. So let's call this app.rb. Who here's worked with Sinatra before? All right, cool. So for those of you who haven't, Sinatra is just a lightweight web framework in Ruby. My guess is that most of us probably use rails more often when we're building stuff for production. Sinatra, I've been surprised how much I used it once I started working at Twilio for the stuff you do, the kind of apps you build with Twilio. It's incredibly useful, because you can build these web apps that just handle HTTP requests in just a single file. So here I'm going to include Sinatra. And I'm going to define a endpoint that will handle a post request at slash message. And the way this is going to work is that when y'all text this number here, Twilio's going to make an HTTP request to this app. And when you make that HTTP request, much like your browser makes an HTTP request to a server, your browser expects an HTTP response back. And so we're going to send back an HTTP response. And that response is going to be what we call twimples, just a set of XML tags that will tell Twilio what you want it to do next. And so we're going to tell Twilio to reply with a message. And that, oops, hello, caps lock. And that message will just say, thanks for the text. And if you want to learn more, twilio.com slash docs, the getting started guide is in Ruby. We'll cover all of this for you. And it's really, like serious, like five minutes from creating an account you'd be sending receiving text messages. It's very similar to Dropbox there. And if y'all want to find me, if you have any questions, you feel free to reach out. I'm Greggy B on Twitter. All right, so that looks good. It looks like I have my slash message, slash response, message, response, looks like I have my quote marks there. So we should be good there. So let's save this and we will start up, oops, we'll start up our Sinatra server. Now the problem right now at this moment is that there's no way for Twilio actually to access this server that's running here. Because much like if you just spun up a rail server on your local machine, there's no publicly accessible URL to get there. So what we need to do is open up a tunnel to it. There is this great utility. Who here has used ngrok before? All right, so if you do any work, I mean really just about any web development it'd probably be useful to you. For no other reason than it allows you to run something on your local development environment and then give a URL to somebody else so they can check that out. But if you're doing any work with web hooks or building any APIs, it's super, super useful. So I'm gonna open up a tunnel that will accept HTTP requests on port 4567. This is the port that Sinatra runs on by default. And you can see here that ngrok has now given me a URL and I can take this URL and I can paste it into the web hook here and I just need to add my slash message endpoint there. So now when y'all text this number, Twilio will make an HTTP request to that Sinatra app that's running right there. So if y'all want to text, text your name to 513-318-3606. Again, that's 513-318-3606. Let me know, shout out if you get a reply back. You got it? All right, great. All right, cool. One more time for those of you who haven't texted in. 513-318-3606. And so this is useful, right? Because, and we can just see the request roll in over here on ngrok and if we come over to our Sinatra server we can see those requests rolling in as well. So this is really useful because now you can text a Raspberry Pi. All right, and so, and folks will use this for things like home automation. You can, they'll use them for things like hooking up to an LED and controlling the LEDs or controlling a display via text message. And so you can text in and you can, was that? Oh, did you get an egg? Uh-oh. All right, well, we'll put it up on the screen later on. It's Greggie B, G-R-E, G-G-Y-B. Yeah, oh, okay. Thank you very much for the heads up on that. So yeah, so now you can text this. And this is really useful because I spent days trying to figure out how to do the same thing on an Arduino U and how to open up a tunnel to it. And it was super difficult to do. So now with Ngrok, you can open up a tunnel, you can access your Raspberry Pi through any publicly accessible URL and also via text message with Twilio. So I'm gonna kill that server. So if anyone texts it, you're not gonna get a response back anymore because I, this wasn't, you know, texting the Raspberry Pi wasn't actually essential to having my dog text me selfies. I want texts to go the other way. I want my Raspberry Pi to be able to send text messages. So I'm gonna create a new script. We're gonna call this send SMS.rb. And here I'll use the Twilio Ruby helper library. And we'll just create a new method here called send text. And send text is going to use my account SID. So this is my, this I'll find here on my dashboard. I'm gonna copy that. And we'll use my auth token, which I will recycle as soon as I get off stage. Please don't get any ideas or take any pictures right now. And so we got my account SID and my auth token. And once I have those, I can then use the Twilio client. What am I doing? You can use the Twilio REST client. I'll create a new one by passing in the account SID and the auth token. And once I have that, I can grab a list of all the messages that have been sent to that phone number that we just purchased. Oh, thank you. Let's copy this. Yep, very good. Man, does anyone do that mob programming stuff? It's kind of what this feels like right now. All right, and now once we have our messages, we can iterate through each message. And with each message, we can, I'll throw a begin in here because sometimes we get a special encoding or whatnot. I can throw this off. I don't want it to ruin it for everyone. But we will try to output the, well, let's have a moment of truth. Did anyone text in anything profane? Did anyone text in anything that would violate the code of conduct? So remember, I have your phone numbers now. So, all right, all right. So we're gonna output what everybody said. So we're gonna output everyone's names. And then we are gonna use the client to create a new message. And that message is going to be to the number the number that that message was sent from. It's gonna be from that same Tulio phone number that we just bought. And we're gonna have a body that's gonna say, here's my real Twitter handle, Greggie B. There we go. And if you all wanna email me, you can, I'll throw that in here too if you have any questions. All right, and I think that should be good. Let's just make sure I got everything all right. So we're creating new message. We need three pieces of information to send a text message. So we need a number we're sending to. And that's gonna be the from of the text that came inbound. We need the number we're sending from. This can be the Tulio number. And then we need a body in that message. All right, and so let's, uh-oh, what are we doing? All right, and so this actually won't do anything just yet, cause I defined a method, but I'm not actually running it. So now let's run it here. And we'll see what that does. All right, cool. So we got everyone's messages that came in. And so now we have a way that we could, when you text that Raspberry Pi, you could text it commands. And we can pull out the actual body of that text and then use it to trigger different actions in Ruby here. Oh hey, Elizabeth, where are you? Hey, what's up? How's it going? Thanks for coming. Man, a lot of y'all participated. So thank you very much. All right, and has anyone's phone lit up yet with a text? You got it? All right, cool. All right, so now we have a Raspberry Pi that can send text messages. So it can receive text messages. It can also send text messages. So thanks for all y'all who participated there. This still doesn't quite get us where we wanna go because we don't have a picture associated with that. So what we wanna do here is actually pass in a URL to this method. And we just need to add a fourth parameter on here. Let's do this. And that fourth parameter will be a media URL. And so this is gonna be the URL of a, the picture that we wanna send. So this is gonna be a publicly accessible or needs to be a publicly accessible URL. But any publicly accessible URL you can pass in here just as the fourth parameter in that picture that media will come through. Typically it's gonna be a picture. You're gonna send animated pictures. You can send gifs. You can send sound files. You can send small movies too. Most of the time it's gonna be a picture. All right, so we're gonna say that, not gonna actually, let me fix one more thing here. I don't need to run this right now because we're gonna call this from different thing in just a second. All right, so, and we'll see if that works here in just a minute. But so now we did two of our three steps. All right, so we took a picture. We sent a text message soon to be a picture message. Now we need to do it all at the push of a button. All right, and so we'll clear this out again. And I'm going to create a new file. And this one will be called push it. And actually let me just look and make sure I named all these right. So take the, all right, cool. All right, so Vem, we'll call this one push it. All right, and for this one we're going to use a helper library called pi piper. And this is a helper library for the Raspberry Pi that lets you interact with the pens that are on the Raspberry Pi that we have broken out to a breakout board that we then have our input from our button coming to. We'll include the module here. And with that module we're just gonna say after pen. And so I have my button plugged into pen four and then I'm gonna say after pen four goes high then do something. And so what's the something that we wanted to do? And that something is we wanted to take a picture, upload the picture and send the text message. All right, so we will require our, we'll do this relative, require a relative. We're going to require relative take picture.rb. I might have put this in here. Require relative and we will do our upload picture and we will require relative our send text.rb. All right, and so now we have the three files that we wrote earlier. Actually, you know, now that I think about this, I didn't actually put this, let's grab our take picture and let's actually put this into a wrong file name. Did I use underscore? Oh, thank you so much. All right, perfect. Here, let's do this. Let's move, send a SMS to send text like that. All right, how's that? And what did I do for in that file? Did I name the, yeah, so I named the method, right? All right, cool. All right, so let's open up our push it again and let's see if it works. If we did this right, it should be as simple as saying now, take a picture and then we will grab a URL by uploading a picture and then we will use that URL and send a bunch of texts using that URL there. All right, so, and then the last thing I need to do is just tell PyPiper to wait. All right, and PyPiper is event driven so what it's gonna do is it's gonna sit there, it's gonna wait to see a high signal on pen four so that's the one coming from the button and when it does it will execute that and we need to run this with just because of the way some of the configuration set up on the Raspberry Pi and permissions to access the devices. We need to run this with RVM pseudo but we'll just run it and we'll call it say push it. Didn't get any errors, it's just sitting there waiting for us. So if y'all in the audience here want to, oh, it looks like we actually ran. Why did we run? Oh, we ran because I included it and ran the Dropbox at the end. I don't think this is gonna screw us up though. So here we'll do this one more time. All right, so we push the button, we're taking a picture, write the picture out. We should see, we probably won't actually see the URL again because we did the puts outside of the method but now we'll be cycling through everybody's name and then we will be sending a picture that has a URL on it. So could you switch back over here to the laptop? As much as I'm sure y'all are thrilled to get pictures from a webcam of the people sitting in this room right here, that wasn't actually the goal. This is what it looks like when we do it with the dog. And so I had to tell her to sit. I don't know if y'all remember from the video you watched when it came in, she hits it pretty enthusiastically. And she comes, press the button, you gotta hold it there because it takes just a second as you saw but then the picture shows up on your phone. So and that's how I taught my dog to text me selfies. So the bigger message, has anyone gotten a picture on their phone? Show up yet? Yeah, all right, fantastic, cool. So just to recap, we used just a couple web services here, right? So we used Dropbox and we used Twilio and then we used this command line utility. And all of the code that we wrote and all of the circuitry that we did was basically just out of the getting started guys for each of these things. So the circuit that's driving this is the second getting started example. The Dropbox code that's running is effectively copy and pasted from the getting started with Ruby guide to the Dropbox API. The code to send a text message with Ruby is basically copy and pasted from the getting started guide with Twilio. And I think that I had so much intimidation about actually working, doing this hardware hacking stuff but I think like a lot of people who once they get into programming feel that same thing. As it turns out, some of the coolest solutions to problems that are out there, right? Like there are problems that seem impossible. Like how do you possibly teach your dog to text selfies, right? But if you break it down into individual components, oftentimes the solutions to complicated problems are just really simple solutions stacked on top of each other. So if you all are out there, you know how to write a little bit of code or if you know how to do a little bit with a Raspberry Pi and you're willing to do some copy and pasting of code even if you've never written that before. I think you'll be incredibly surprised with the things that you can do in the world of hardware hacking with a Raspberry Pi and just a little bit of Ruby. So again, my name is Greg. I really appreciate you all hanging out. Thank you very much.