Create a gist now

Instantly share code, notes, and snippets.

require 'rubygems'
require 'mechanize'
FIRST_NAME = 'FIRST_NAME'
LAST_NAME = 'LAST_NAME'
PHONE = 'PHONE'
EMAIL = 'EMAIL@provider.com'
PARTY_SIZE = 2
SCHEDULE_RANGE = { :start_time => '19:00', :end_time => '20:30' }
def start_url(restaurant=2086)
return "http://rez.urbanspoon.com/reservation/start/#{restaurant}"
end
def to_minutes(time)
hour, minutes = time.split(':')
raise "Malformed time: #{time}. Should be in the HH:MM format." if hour.nil? || minutes.nil?
return (hour.to_i * 60) + minutes.to_i
end
url = start_url()
agent = Mechanize.new { |agent|
agent.user_agent_alias = 'Mac Safari'
}
# Get the start page
start_page = agent.get(url)
# Bail if there are no reservations
exit if start_page.forms.count != 1
# Fill in the details for the reservation
start_form = start_page.forms.first
start_form.size = PARTY_SIZE
# Verify if the available times are in the allowed range
available_times = start_form.field_with(:name => 'seating_time').options
possible_times = available_times.select do |time|
(to_minutes(SCHEDULE_RANGE[:start_time])..to_minutes(SCHEDULE_RANGE[:end_time])).member?(time.value.to_i)
end
# Select the first of the possible times for the reservation
start_form.seating_time = possible_times.first
# Submit the details and get back the contact form
contact_info_page = start_form.submit
# Check for the existence and get the contact form
exit if contact_info_page.forms.count != 1
contact_form = contact_info_page.forms.first
# Fill in the contact details
contact_form["user[first_name]"] = FIRST_NAME
contact_form["user[last_name]"] = LAST_NAME
contact_form["user[phone]"] = PHONE
contact_form["user[email]"] = EMAIL
# Submit the contact details and get confirmation page
confirmation_page = contact_form.submit
# Confirm the reservation
exit if confirmation_page.forms.count != 1
confirmation_form = confirmation_page.forms.first
final_page = confirmation_form.submit
puts "Got reservation for: #{start_form.seating_time}"
@frankcaron

This is genius. Awesome job.

@anthonybishopric

Well done. I also wrote (and grabbed) a SBP reservation using phantomjs, but I definitely did not post it because there is zero incentive to share it. :P

http://www.youtube.com/watch?v=A8I9pYCl9AQ

@jkaihsu
jkaihsu commented Jul 25, 2013

nicely done

@maxubd
maxubd commented Jul 25, 2013

Nice work! Just don't tell anyone else in Chicago, please!

@mattkenefick

I can't wait to tell Chicago about this!

@linuxbiker

we have a place that sends out reservations on a web page like that here in Athens,GA. I tried a few times to get a reservation as soon as it came online, but always failed. It isn't a restaurant, but a small once a month table of people. I even tried copy & paste data and it wasn't fast enough. I might try making this work for our site - http://www.thefourcoursemen.com/about/

@mattcawley

Very cool!

@baiIey
baiIey commented Jul 26, 2013

Great job, here.

@chuckreynolds

claps awesome

@LabLayers

Genius idea! If only UrbanSpoon was programmed to be completely botproof... :P

@chrisloughnane

cheers :)

@sarahduve

Do you have similar code for OpenTable?

@plc
plc commented Jul 29, 2013

how often did you run this?

@diogomonica
Owner

I started out by doing it once a minute. That seemed enough to get reservations initially (it was a once a minute crontab).

The new bot that I'm developing does checks every 5 seconds.

@FelipeVargas

genius

@kiquenet

Great! It would be interesting powershell script or .NET :-)

@spencerthayer

So how does this work? Is a cron job constantly running in the background? Is this running locally or on a server?

@sharksfan98

Genius.

@azadibogolubov

I love this. Did something similar in Python for registering for high-demand classes in college. This is a great time to be a programmer.

@Someguy01

Can someone tell me how to use this? Also does it work on ticketmaster as i might try to get some tickets for minecon. Also should i make 1 bot on a computer and one on the other to buy tickets for 2 people such as me and my friend? Help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment