When JavaScript Gets IIFE

Recently, while working on a JavaScript project, I experimented with putting a closure a loop. It did not work, and for reasons I couldn’t initially explain.

After a good bit of research, it turns out I had stumbled into a well-understood issue (some call it a bug) known as “fold over.” In this post, I’ll go over what “fold over” means and a few alternatives for counteracting it, including a very useful design pattern known as an Immediately Invoked Function Expression (IIFE).

Background: A Game of Blackjack

The project was to build a simple version of the game of Blackjack in JavaScript. I had set up the game such that each round could have any number of players and rounds would end with an array of each player and their card total (with face cards worth 10 points and aces worth 1 or 11).

Introducing Stackup

"StackupApp"

StackupApp is AngelList for tech stacks. The app seeks to map out the current technology landscape of the startup ecosystem. The app injests startups from the AngelList API and tags each startup with programming language and tech stack keywords from Indeed job postings.

Currently there at 5,318 New York City-based startups on StackupApp, of which 693 have been tagged.

Technical Features

APIs and OAuth

In addition to retrieving startup information from the AngelList API and job postings from Indeed’s API, StackupApp also enables users to sign in via AngelList OAuth. The OAuth implementation relies upon Devise and OmniAuth.

If the user is a Founder of a AngelList startup also on StackupApp, they will see a Manage section on the startup’s page and their profile page. The Manage section enables the user to Edit the startup’s tags (under development), Unclaim or Deadpool the startup.

If you don’t have an AngelList profile or would like to use a demo account, you can sign in via AngelList OAuth with the StackupApp test account credentials (hello at poemtoday dot com, abcd1234).

"Manage"

RESTful Routes

StackupApp is built with Rails, and takes full advantage of the framework’s REST conventions. The Unclaim and Deadpool buttons intiate DELETE actions on the UserStartups and Startups controllers, respectively, and can only be access as an authenticated user.

Backgrounds jobs with Sidekiq and Redis

When a user has signed in via AngelList, the app makes an API request to AngelList to retrieve the user’s startups. This request is made via a background job to improve performance, specifcially via a Sidekiq Worker and Redis.

Scopes and counter_cache

The app displays startups and technology tags by popularity scopes. Tag popularity is determined by counting the number of StatupTags or job postings with each tag. A counter_cache is used on the StartupTag table to improve performance. The AngelList API provides follower_count which serves as the startup popularity metric.

The app enables users to search_by_name for startups or search_by_tag for tecnologies, which is implemented with the pg_search gem on the Startup model. Only startups that have been tagged are shown in the index and search results, while all startups are searchable by name.

Continuing Development

Continuing development plans include moving the frontend into Ember.js. Also, expanding to SF and Boston.

Twilio Text-To-Speech in Rails 4

This post walks through the steps I took to set up text-to-speech in a Rails 4 app. To learn about other options for implementing text-to-speech in web apps generally, see Text-To-Speech Options for Web Apps.

Also, the Twilio blog has a tutorial worth reading, Integrating Twilio With Your Rails 4 App, but it does not cover setting up the crucial Twilio.Device, the “conduit” for TTS and a lot of other Twilio API goodness, in Rails 4.

Before we get started, note that Twilio.Device only works when connected to the internet. So you can’t test Twilio.Device from localhost. Instead, you’ll need to expose your localhost to the internet with a utility called ngrok. (See #9 below.)

In order to set up Twilio TTS in a Rails 4 app, we need to complete 10 steps.

  1. Sign up for Twilio
  2. Install the twilio-ruby gem
  3. Add endpoint for Twilio
  4. Disable DSRF Detection on Twilio endpoint
  5. Create a TwiML App
  6. Setup Capability Tokens
  7. Put Capability Token and text in an HTML form
  8. Add Twilio.Device javascript
  9. Setup ngrok to test
  10. Deploy

Text-To-Speech Options for Web Apps

While I was building PoemToday, I wanted to add a feature that enabled users to play any poem aloud in a robot voice. If the inspiration for PoemToday, The Writer’s Almanac, had Garrison Keillor’s voice coming over the NPR radio waves every morning, then my app would have the voice not of a killer robot, but a Keillorbot.

This proved to be easier said than done. First, there was a dearth of good quality options for text-to-speech that fit right into Rails. Second, with the Twilio implementation I chose to make, there were a few configuration steps between Twilio and Rails that were neither obvious nor well documented. You can read more about the steps I took to implemet Twilio here.

TTS Options for Web Apps

Currently there’s a dearth of good quality text-to-speech options for web apps. I can’t really speak to mobile and desktop apps, but I believe those those platforms offer native TTS capabilities which developers can hook into.

Some web app options, like AT&T, were paid services that seemed to actually require more of an integration hurdle and impose all kinds of usage restrictions. Others like the tts gem relied on a Google Translate hack which limited the spoken text to only 100 characters, about a sentence. A haiku might fit under that limit, but not a medium-length or longer poem. I also reached out to Wit.ai, but they said they don’t offer TTS yet.

The better options were Twilio and tts-api.com. Twilio makes text-to-speech available through Twilio.Device, an API object that effectively turns your users’ browser into a phone or “soft device”. Meanwhile tts-api.com is just a one-page website with a single textarea on a form that returns an mp3 audio file when submitted. Nice and simple!

Even though it was probably the best option in terms of performance, I didn’t want to download and store 6,000 mp3 files from tts-api.com, one for each poem, and rack up hosting fees. I could’ve also had the mp3 file from tts-api.com pop up in a new window, but I dislike pop ups (they’re terrible user experience) so I went with Twilio.

Also, while researching this post, I found the espeak-ruby gem, which I’ll haven’t tried out… I’ll have to come back soon and post an update. In the meantime, I’m glad I got a chance to figure out the Twilio implementation as I learned a lot.

See the steps I took to implement Twilio text-to-speech in Rails 4.

How I Built PoemToday

Today I’m introducing PoemToday, a random poem generator that’s powered by user behavior. Here is the story of how it works and how I made it.

PoemToday (also on Github) is a Rails web app that statistically generates a poem based on its users’ profile and behavior. Each of the 6,000 poems on the site actually has a link wrapped around every word in every poem. When a user clicks one of the words, the site initiates a search of its database for the best-matching poem and redirects the user to the top result, alongside with the top image from the Flickr API for that word.

1
2
3
4
5
6
7
8
9
def save_top_result
  @poem = @results.inject do |winning,result|
  winning[:match_score] > result[:match_score] ? winning : result
  end
end

def get_image_url(keyword)
  flickr.photos.search("text"=>"#{keyword}", "sort"=> "relevance").first
end

Behind the scenes, PoemToday is storing information about all of the words the user has clicked and the poems the user has visited in a temporary session. When the session has enough data, it statistically generates a completely unique “ephemeral” poem with a statistical process known as a Markov chain.

Introducing Tender

Tender is a social payments app (think Venmo) for Bitcoin. Users can send or receive any amount of Bitcoin, including extremely small amounts which can be used to validated the identity of counter-parties.

I built Tender (also on Github) with Chris Kohlbrenner. I came up with the initial idea for the project as a Bitcoin dating site… hence the triple-play on words with the name “Tender”. However, Chris and I decided to generalize the app and make it usable (or at least instructive) for other open source projects as a general social messaging utility.

Why Bitcoin Messaging?

Bitcoin gets a lot of hype these days, but after working with the cryptocurrency a bit, I really do see its potential to transform online payments and much more. For example, a messaging system can require a very small amount of Bitcoin get sent with each message as a way to prevent or at least deter bulk volume spammers. After practicing our web development skills, our main purpose in building Tender was to demonstrate this anti-spam concept.

We used Ruby on Rails as the framework and built the Bitcoin transactions features with the Coinbase API and the messaging functionality with a gem called Mailboxer. In the process of weaving those two features together, we learned a lot about them. Payments and messaging share the concept of “credits” and “debits” to a balance or mailbox. Kind of like double-ledger accounting, we had to do a credit and a debit whenever a user sent money and a message to another user, and vice-versa. You can see that code play out in code below.

Tender Send-Request Bitcoinsource
1
2
3
4
5
6
7
8
9
10
11
def send_message_and_bitcoin
  current_user.send_message(@recipient, @message='You\'ve got Bitcoin.')
  current_user.send_bitcoin(@recipient, @amount)
  debit_balance(@amount)
  credit_balance(@recipient, @amount)
end

def send_message_and_request_bitcoin
  current_user.send_message(@recipient, @message='Send Bitcoin please.')
  current_user.request_bitcoin(@recipient, @amount)
end

Coinbase and Typeahead.js

To build Tender, we used Devise and Omniauth to authenticate users, enable them to sign in via Coinbase and to validate their balances on Coinbase. The app features a lot of validations and notices to users to confirm that their transactions go through when they should and shows descriptive alerts when they shouldn’t, such as when the user has insufficient Bitcoin balance.

We also made it easy for users to find each other by implementing an autosuggest user search feature with Twitter’s Typeahead.js, and brought the user objects to the views with the gon gem. Finally, Tender features a robust testing suite with Rspec and Capybara, at 92% code coverage.

This was a very interesting project on many levels, from working with a new payment type like Bitcoin, to getting deep into the mechanics of messaging. I also learned quite a bit about implementing complex Javascript features in Rails.