Happy election day!

We’re excited that it’s finally election day and sons and daughters around the country are casting their vote.

Let your mom know you’re voting by checking in and using #mom!

0 notes

Creating a foursquare connected app overnight: #mom code review.

We built and launched the connected apps version of #mom in one long night a few weeks ago and we’d like to walk through some of our code. Foursquare’s connected apps platform is just a few months old and still in developer preview so we wanted to help other developers get started.

Foursquare allows 3rd party apps to (1) receive a push feed of check-ins, (2) reply to check-ins with text and a link to a custom web view or your native app, and (3) post to the activity feed when an user connects or interacts with your service. For #mom, this is exciting because we can suggest that you call your mom after a check-in rather than hope you remember to include “#mom” in the message (aka a shout in foursquare data model land). There are multiple places to provide users value and delight through a backend action, simple prose, and links to your native app or web UI.

We’re going to walk through replying to check-ins, controlling your service from inside foursquare, and creating posts in the activity feed. Our goal was to build this in one night (10pm to sunrise). We’re assuming you’re already connecting users over OAuth, receiving real-time push check-ins, and familiar with foursquare’s data model as we described in our prior technical post.

First, we need to choose if we want to respond to a given check-in (we don’t want to spam!). Foursquare has an extensive venue categorization taxonomy, from broad levels like parks and recreation to granular places like volcanoes; yes, we have users checking in atop hot lava. You can browse the venue categories online, though we queried the JSON API and dumped to Google Docs for easier person and machine-readability.

We spent much of the night crafting close to 60 quirky messages based on the venue’s category. Connect the app and see if you discover them all! 

Foursquare orders each Reply based on response time so we need to be speedy. Replies contain a customizable short message with an optional click through link and are displayed asynchronously in the user’s post check-in screen. We noticed this can appear buggy as new replies are rendered as they come in.  

We use the click through link as the trigger to send a call or a text depending on our user’s preference.  This was tricky because we don’t receive any information from foursquare when the user clicks the link; we only control the URL.  Each link therefore needs to be unique per check-in so that we can look up in our database who to call or text and what to say.  The links also need to be unguessable, so you can’t go to hashtagmom.com/easy-to-guess and call your friend’s mom. We accomplish this by storing a distinct random string for every check-in, generated by Ruby’s SecureRandom library. We ensure each token is unique by, elegantly, doing mighty brute force— continuously generating tokens until we find one unused. We could improve this by pre-computing a list of tokens or using some kind of UUID if it were a performance bottleneck, but we hit zero conflicts in our testing of 5M tokens and moved on.

Once we generate a link and text, we send a reply to the API endpoint at https://api.foursquare.com/v2/checkins/checkin_id/reply.  Composing the request is easy, but we ran into a roadblock getting foursquare to accept it. Unless otherwise instructed, foursquare defaults to their oldest API, so you need to explicitly instruct it to route your request to the correct endpoint version.  To use the latest API, send a { :v => date } parameter along with your request, where `date` is the most recent date when your app worked with the newest API.  We developed this on August 17th, so we use “20120817”.  Having to provide a version date along with  “/v2/” in the URL is confusing. All set with constructing the reply? Don’t forget to use https:

After a successful call or text, we wanted to create a Post for that check-in, which looks like an auto-generated comment in the activity feed on both mobile and web. This is much simpler than sending replies and can include custom text and a custom link. There is a lot of new jargon in terms of (pun!) ways to communicate with the user but at least the Post syntax is similar to a Reply:

A brief aside— you’re required to provide a privacy and terms of service statement to be officially blessed into their directory. We used Docracy and branched their open privacy statement and adopted it for our use (feel free to branch ours too!).

We’re looking forward to the evolution of the platform and hope to see a full fledged marketplace discovery section within the application, clearer policy about how relevant connected apps are chosen and ordered in the check-in view, and more clever experiences that provide value and do not tire after a few uses. Foursquare uniquely has the attention and context of people when they are at places and we’re excited to see how others bring the joys, efficiency and serendipity of the internet to us when we most and least expect it.

To get started, review their technical documentation and guidelines which gives details and a sense of the spirit they’d like apps to embrace but it’s still very opened ended. If you have questions, please tweet or say hello at the bicoastal foursquare hackathon on Nov 3rd; @jeff_weinstein in SF and @scpike in NYC.

1 note

#mom foursquare connected app

We were super excited to hear about the foursquare connected apps platform a few months back. We wanted to join the fun, so we’re launching a hashtagmom connected app within the foursquare platform.

When you check in to a venue that we think you’re likely interested in telling your mom about (e.g. an airport, train station, hotel, home, etc…) we’ll send you an after check in prompt where you can simply one-click initiate a call or text to your mom. Nothing new to sign up for, just start using it today.




You can still add #mom to your check in message and we’ll call or text your mom letting her know you got there safely from any venue.

Adding third party data and services into the foursquare mobile application opens up new ways people can interact with the world around them. We’re the first Twilio powered foursquare connected app so we’ll post another deep technical dive overviewing how we ported our application to the foursquare platform and what changes we need to make to launch this new way to keep mom in the loop.

We’re interested in ways that location context can be combined with sharing, communication, and other types of channels to enhance our day to day lives.

Let us know what you think. 

Safe travels,
Jeff and Steve

p.s. we have dozens of fun reminders to call your mom based on where you check in, see if you can discover them all!

1 note

Cops and Flowers

Thanks to the many of you for trying out our fun little service. We’ve received some wonderful tweets, emails, and high fives in the last few months but wanted to share this story since we think it really takes the cake.

We’ve changed the names to protect the innocent. Long story short, we learned that sending flowers has been the largest expense in running this side project: larger than Amazon hosting, Twilio per call and SMS send, and domain registration… combined!

“Hi there,

I hope you get as much amusement out of this as my family did. :) We will be telling this story and laughing about it for years.

My mom loves to know where I am at all times. I don’t mind…my life is not that interesting, haha. She has cancer and I’m six hours away, so whatever makes her more comfortable. I set up “Find My Friends” on our iPhones so she can track me that way, but a week or so ago it didn’t update properly and she was very upset when she thought I was someplace I wasn’t. I read about #mom a few days ago and decided to set it up over the weekend. I did a test check-in and showed my mom how it would look on her phone, but thought I may never have a need for it between Find My Friends and ordinary texting.

On the long drive home yesterday, I decided to stop and meet a friend for dinner. I knew my mom would see my little dot stop moving on Find

My Friends, so I decided to try out #mom when I checked into the restaurant on FourSquare. I sent a message that was something like “Stopping for dinner and visiting Meredith!” My parents know this friend, so I thought they might text me back and tell me to say hi for them, or they might try to respond to the #mom notification and be confused when it didn’t go through, but I’d just explain it to them later.

40 minutes later as I was leaving the restaurant, I checked my phone and saw that I’d just missed a call from my dad. He didn’t leave a voicemail which usually means I don’t need to call him back, but since it’s only been a few minutes I decided to call anyway. He told me my mom had gotten a weird text that was phrased very strangely and he thought I was in trouble. I laughed and explained…apparently my mom had forgotten when I’d shown her how the text would look. He said something about how he had called 911 and the state police and I laughed again, it sounds like something my dad would say as a joke. 

Then I realized he was serious.

Apparently the first part of the text that says “Your daughter Abby would like to tell you” made them think a stranger was with me and I was telling them to text something for me. And the last part of the text that says something about a help code made them think I was in trouble and was trying to covertly let them know. He called 911, the state troopers and was about to call some undercover cops they referred him to before he decided to try calling me!

Why didn’t he just call me first? Because mom tried to reply to the text message and it didn’t go through, and she thought she was replying to me and my phone must be disabled. And if I was being abducted, could they believe anything I said anyway? Good grief.

So I spent the rest of my drive (about 4 hours) carefully below the speed limit because I had no clue how I would explain all this to the police if they pulled me over and my name came up!

Anyway, the bottom line is, I would LOVE to see a way to customize the rest of the message that gets sent out. If it had just started with “This is an automatic notification” that would have been so much better for my non-tech savvy, extremely forgetful, overly paranoid parents.

Just had to throw my two cents out there after this experience. :)

Thanks,

-Abby”

We checked the logs and found some enlightening context:

12:31pm: Abby checked into Jackson Plaza and wrote “Stopping for dinner and visiting Meredith! #mom”

We processed the checkin immediately after that. We normally automatically add “This is a service from hashtagmom.com” to the end of all SMS message but since the checkin has a lot of characters (long venue name and medium long message) the total SMS length was greater than 160 characters. So we have a rule that just removes the “This is a service from hashtagmom.com” to attempt to fit it within one SMS.

12:46pm: we get a text message reply back from your mom with the message “K! Who is this???”

12:46pm: we auto replied back with the message:

“Welcome to Twilio SMS. Configure your number’s SMS URL to change this message.

Reply HELP for help.

Reply STOP to unsubscribe.

Msg&Data rates may apply.”

I can totally understand how this would have created an issue. We’re considering doing a few things in the future depending on what is technically feasible:

1. Change the message people get when they text our number to be something friendly

2. Redirect the text messages from a mom back to the son or daughter 

3. Send two text messages when it’s longer than one to ensure people know it’s from a service

Well, we were so touched by this story and a bit guilty about our corner case coverage that we reached out to Abby and her mother to try and make this right. We sent her mother flowers from a local florist. We even already had her phone number on file to confirm with the flower delivery company!

1 note

Foursquare API, and SSL, and OAuth. Oh, my!

Continuing our deeper dive into the nuts and bolts of how we built #mom, let’s walk through how we used the foursquare API. We we wanted the foursquare platform to: (1) handle user authentication, (2) supply general user data, (3) retrieve user checkins, and (4) promote the service by displaying #mom in the friend checkin feed.

Much like Twilio, our first step was to register our application with foursquare. They call this process “register a new consumer.” It made sense, after a while, since as a developer we are “consuming” foursquare data. Foursquare also asks you for a website and callback URL. We hadn’t settled on the hashtagmom.com domain yet (my original idea was theresafe.ly) but luckily it doesn’t matter what you put into this field.  The callback URL is more important and a not well documented. We had issues with invalid redirect uri errors when specifying the full callback path (http://www.hashtagmom.com/path/to/callback) for our app. If instead you just give foursquare the hostname (http://www.hashtagmom.com/) they will allow you to specify any path under that host in your OAuth2 request, so that seems like the way to go.  The foursquare API was also easier to work with locally than Twilio, as OAuth2 uses a browser redirect that works to localhost, so you don’t need a localtunnel set up. Please read our previous Twilio post if this distinction is unclear.

With the goal of connecting to foursquare and retrieving data from a simple standalone ruby program, I Googled “foursquare gem.” Unfortunately the first result, in my version of Google, is an out of date gem. I futzed with that until I stumbled upon a more recent gem called, wait for it, foursquare2 gem. Foursquare’s libraries page points to the latest gem so it’s always a good tip to just follow their official links rather than my brain-ingrained-let’s-Google-it approach. There is also a foursquare-api gem but I haven’t used it.

Ok, so we were able to query foursquare and retrieve data from endpoints that only required “userless” access permission. These are endpoints like get information about venues, tips, and lists. To access checkin details, user data, or many of the other interesting bits available in the platform, you need to act “as” the user— you need a user to authenticate your application with foursquare and explicitly get permission to query the platform as if you were that user.

oauth2The following is a  bit of an aside and not specifically related to any particular platform but necessary to understand. You’ve likely connected to Facebook before. You’re on SomeGreatSite.com, they have a connect to Facebook button, you click it, and now you’re redirected to a Facebook page that read, “Hi, would you like SomeGreatSite to have access to x, y, z Facebook permissions?” Yup, hit yes and you’re redirect back to SomeGreatSite.com. This flow is brought to you by OAuth2: check out this technical description and foursquare’s overview. From the developer’s perspective: you a user on your domain and want to query an API on that user’s behalf. Rather than ask for andstore a user name and password, you direct the user to the service and wait to hear back if you have permission or not. If you do get permission, you get a special token that is specific to that user. (Remember going to the arcade as a kid and getting special tokens that only fit into the video game machines?) Now, you can query the other service with this token and act as the user. The developer does not have to see or store the user’s authentication details. If the user wants to revoke your site’s access to the platform, they can just tell the platform to stop accepting that token. Change of password, no problem. Badaboom. 


We’ve shipped the user off to foursquare but does foursquare know how to return the user back to us? How do we know which user they’ve sent back to us? The callback URL! You inform foursquare which application you are with your client ID and secret on the redirect call  and foursquare calls your application back at your predefined URL. We can test this locally since a localhost callback URL will work. Just set up a route in Rails that handles the URL call: in our case this was /foursquare_callback and we handle this call in our Users controller. Foursquare returns the user’s access token in the callback URL which you can parse from the params hash. The next problem: which user are they referring to? We had a few options: (1) we thought about passing some user ID to foursquare and then parsing it back out of the callback but we’re not sure that would work (not to mention it seemed like a bad idea to pass a 3rd party an app specific user specific ID), (2) matching some foursquare user data against our user information but we already removed email address from the sign up process (and this also felt wrong at a gut level), (3) storing an ID in the browser cookie for that user’s session.

Rails easily allows you to store a session ID in the user’s browser’s cookie and access per-session data in your controllers. We bank on the fact that the callback URL will occur within the same session. Rails queries the user’s session from the cookie and then we look up which user had that session ID. We also store the OAuth2 access token (a string) in the user object and use it anytime we need to query foursquare on the user’s behalf.


It’s a windy road to get started with user authentication. You have to play by the platform’s rules. Once you have an access token, you’re ready to query!

We want the foursquare checkins as they happen. When someone includes “#mom” in his or her shout (foursquare’s field name for the 140 character message per checkin), we want to kick off a process that parses the message, looks up the user’s settings for call or text and tells Twilio to go. Foursquare has two ways to get checkins for a user: pull and real-time push. During the development process, we used the pull API to access the latest checkins and manually scheduled when to refresh this data. We’d briefly store the checkins then cycle through them looking for “#mom” and call the next step. This helped us manually test the service and we could even generate fake data within our database saving us an embarrassing number of #mom public checkins (though I generated like 20 of them in production the night we got it all working). We figured we could get push working later and guarantee that our data flow worked without the need for push. Push also requires SSL which I’m not aware you can do in local testing. powered by foursquare
Handling both push and pull calls from foursquare was made simple by abstracting checkin processing into a Checkin model. This model knows how to send out calls or texts based on the information contained in a checkin, and doesn’t care how that checkin got created.

Pulling data from foursquare is more straightforward than receiving pushes.  One tricky part is that foursquare doesn’t take care of de-duplicating the checkins they send you, so you have to make sure not to process the same checkin twice. Here’s our pull code, which fits nicely in the User model:



With this code, we can dump a User’s latest unprocessed checkins into our database, where we can manually process. We considered using the delayed job framework to pull and process checkins in the background, but eventually decided to take a shot at hooking into the push API.  

For push, foursquare posts to your servers whenever an authorized user has checked in to a venue.   The complicating issue that kept us from starting with push is similar to the problem we ran into with Twilio— it’s a pain to use these webhook APIs from a local development environment.  Foursquare’s API was even more complicated in this regard, as they only allow pushing of data over SSL. This ruled out the localtunnel solution from Twilio, and we never succeeded in pushing data to our local servers. It would be awesome if foursquare could allow non-SSL connections for testing (maybe restricting to only getting your personal checkins pushed). We would also be happy with a solution similar to what Stripe does with their Webhooks framework, where they send you a non-sensitive event ID that you can then use to make a secure request to their API from your server.

Regardless, we needed to get SSL up and running in production even if it wouldn’t work for development. We’re using heroku for our hosting and they offer free SSL via their *.herokuapp.com certificate.  This SSL isn’t useful for user-facing pages, 

heroku

since we’d have to redirect people away from www.hashtagmom.com to the scary-looking hashtagmom.herokuapp.com, but is perfect for giving foursquare a secure path to post to.  Once we had a valid SSL-enabled path for foursquare, processing the push data itself is straightforward:



Getting push working was a huge win for us.  We’ll process a checkin within seconds of it being made.

Like many things, the first time you get this all set up is much harder than the second attempt. This workflow touches many different technology stacks (HTTP, 3rd party APIs, local development, databases, browser sessions, security, user permissions, authentication through OAuth2, and a few others) so it’s not easy to just sit down and do it. I highly recommend working with a friend so you can catch each others mistakes and talk through what each part of your program intends to do before diving into a Google or StackOverflow-athon of article reading and reckless Github code copy and pasting: it won’t work. Writing about your efforts afterwords clarified the process as well; it feels good!

If you have any questions, would like to see more code snippets, or have other topics you’d be interesting in reading about please let us know.
27 notes

Recent articles about hashtagmom.com

We’re so excited so many people have signed up and given feedback on the service. Here are a list of the recent articles people have written. Thanks ya’ll!

0 notes

Which cities love their mom’s the most? NYC > SF

1 note

Ok, this is just too funny!

Ok, this is just too funny!

0 notes

Twilio code walkthrough

We built #mom as a lil side project to learn the a few platform APIs and get over our coding writer’s block and wanted to share engineering pointers (get it!) we learned. Let’s start with Twilio! 

Twilio is a platform to initiate and interact with phone calls and SMS in high level programing languages. It’s pretty hot.
 
We signed up for Twilio, got the application and secret codes, and registered a phone number in their “Sandbox”.  The sandbox lets you send calls and SMS messages to your own phone without putting any money down. This was really helpful, and our first success was a standalone ruby script.  For the actual app you could roll your own client (they provide a few links to Ruby resources), but the official gem is the way to go.
 
Okay, so we had the standalone .rb running and it made a phone call. It was pretty exciting to hear that first ring. We were pumped. I (Jeff here!) struggled for a while to integrate Twilio into our Ruby on Rails project. The text messages were working well but Twilio has a different protocol for making phone calls.
 
First you create a Twilio object with the correct authorization (the codes from the site), you initiate the call, but then there was this strange URL callback. After some more Googling it made more sense: Twilio rings the phone but when the person answers, it needs to know what to do. Twilio “calls back” to your application at some URL you specify (in our case /handle_call). I had the callback set up correctly: the route captured the incoming URL, it called the correct controller method, but the phone calls just kept hanging up with out any speaking.

Why?! Well… we were still in development running on localhost. How was Twilio going to call back to our measly little localhost? Steve came to the rescue and found a post from someone at Twilio about how to route external URL calls back to a localhost. That was super helpful. Twilio needs to make this a lot clearer in their documentation.

Here is a peak into the code for how we used Twilio.

How we initialize a Twilio request, what we have to store on our end



Linking across Twilio requests



TwiML response for the ‘1 to record, 2 to replay’
2 notes

International usage! Bienvenue, Willkommen, Anüge, Irashaimasu!

International usage! Bienvenue, Willkommen, Anüge, Irashaimasu!

1 note