Skip to content

Instantly share code, notes, and snippets.

@brodygov
Created September 5, 2019 22:13
Show Gist options
  • Save brodygov/305584ecbe3a7afcc01746ce97a7444e to your computer and use it in GitHub Desktop.
Save brodygov/305584ecbe3a7afcc01746ce97a7444e to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'bundler/setup'
require 'date'
require 'json'
require 'rest-client'
DefaultStart = '10:30 AM'
DefaultEnd = '06:30 PM'
def usage
STDERR.puts <<EOM
usage: #{$0} COOKIE_FILE DATE DESK_ID [START_TIME] [END_TIME]
Create a reservation of the given resource on the given date at the given time.
DATE must be formatted as YYYY-D-M, with no leading zeroes.
ex: 2019-9-3
COOKIE_FILE: Path to a file containing the desired Cookie header value.
DESK_ID: Bookit/Agilquest "ouidResource" ID of the desired workstation. You can
find this by mousing over the link to view a given Room/Resource.
START_TIME: defaults to #{DefaultStart.inspect}
END_TIME: defaults to #{DefaultEnd.inspect}
EOM
end
if ARGV.length < 3 || ARGV.length > 5
usage
exit 1
end
cookie_file = ARGV.fetch(0)
cookies = File.read(cookie_file).chomp
start_date = ARGV.fetch(1)
end_date = ARGV.fetch(1)
desk_id = ARGV.fetch(2)
start_time = ARGV[3] || DefaultStart
end_time = ARGV[4] || DefaultEnd
RestClient.log = STDOUT
# This is stupid, but evidently necessary to avoid server 500s.
RestClient::Request.execute(
method: :get,
url: 'https://bookit.gsa.gov/mobile/menuAction.do?pageForward=create_own_transaction',
headers: {
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',
'Cookie' => cookies,
}
)
headers = {
'Sec-Fetch-Mode' => 'cors',
'Sec-Fetch-Site' => 'same-origin',
'Origin' => 'https://bookit.gsa.gov',
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => '*/*',
'Referer' => 'https://bookit.gsa.gov/mobile/menuAction.do?pageForward=create_own_transaction',
'X-Requested-With' => 'XMLHttpRequest',
'Cookie' => cookies,
}
params = {
'startDateFormatted' => start_date,
'endDateFormatted' => end_date,
'calendarMinDate' => Date.today.to_s,
'selectedRegionId' => '1',
'selectedLocationId' => '1',
'selectedFacilityId' => '2',
'selectedFloorId' => '118',
'selectedCategoryId' => '2',
'selectedTypeId' => '-1',
'searchType' => 'byDate',
'dateType' => 'standard',
'startTimeInternal' => start_time,
'startTimeInternalDropDown' => start_time,
'endTimeInternal' => end_time,
'endTimeInternalDropDown' => end_time,
'roomName' => '',
'wsSearchAttribute[0]' => '',
'wsSearchAttribute[1]' => 'false',
'wsSearchAttribute[2]' => 'false',
'wsSearchAttribute[3]' => 'false',
'wsSearchAttribute[4]' => 'false',
'wsSearchAttribute[5]' => 'false',
'wsSearchAttribute[6]' => 'false',
'wsSearchAttribute[7]' => 'false',
'wsSearchAttribute[8]' => 'false',
'wsSearchAttribute[9]' => 'false',
'wsSearchAttribute[10]' => 'false',
'wsSearchAttribute[11]' => 'false',
'wsSearchAttribute[12]' => 'false',
'wsSearchAttribute[13]' => 'false',
'ajax' => 'true',
}
RestClient.log << 'Params: ' + params.inspect + "\n"
resp = RestClient::Request.execute(method: :post, url: 'https://bookit.gsa.gov/mobile/setupOtherReservationsAction.do', headers: headers, payload: params)
# Response is paginated, so we can't be sure that our desired workstation is on
# the first page. Just do a sanity check to see if we got any results at all.
unless resp.include?(%{<a href="javascript:detailsDialogAjaxCall('/mobile/viewResourceDetailsAction.do?ouidResource=})
warn 'Failed to find expected content in response:'
warn JSON.dump(response)
if ENV['DEBUG']
require 'pry'
binding.pry
else
raise "Could not find expected link in response: #{resp.inspect}"
end
end
headers = {
'Sec-Fetch-Mode' => 'cors',
'Sec-Fetch-Site' => 'same-origin',
'Origin' => 'https://bookit.gsa.gov',
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => '*/*',
'Referer' => 'https://bookit.gsa.gov/mobile/menuAction.do?pageForward=create_own_transaction',
'X-Requested-With' => 'XMLHttpRequest',
'Cookie' => cookies,
}
params = {
'sortPagingUrl' => '/mobile/searchResvListResultsAction.do',
'ouidResource' => desk_id,
'reservationName' => '',
'attendeeCount' => '1',
'ajax' => 'true',
}
resp = RestClient::Request.execute(method: :post, url: 'https://bookit.gsa.gov/mobile/resvXpressMakeSelectResource.do' , headers: headers, payload: params)
if resp.body.include?('<span id="errors">')
warn 'Error!'
warn resp.to_s
if ENV['DEBUG']
require 'pry'
binding.pry
else
raise 'Request resvXpressMakeSelectResource.do failed!'
end
end
SuccessResponse = <<EOM
<input type="hidden" id="initFunction" value="document.location.replace('/mobile/startPageHomePageAction.do')"/>
EOM
if resp.body.include?(SuccessResponse.strip)
puts 'SUCCESS'
else
puts 'Unexpected response, but we got a 200:'
puts resp.body
require 'pry'
binding.pry
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment