AT&T Store Apple iPhone 3G preorder status checking
I have pre-ordered Apple iPhone 3G from my neighboring AT&T store last Sunday (Jul 20). I have done this as purchasing from the Apple Store wouldn't let me to apply my FAN discounts on the plan. Applying it latter would reflect only after a couple of billing cycles. Also I don't wanna get into the crazy line. I didn't join the true Apple cult yet. I was just curious about the status of the pre-order and I checked the status online and found that the status query mechanism can be exploited to post automated queries. Here is a small ruby script that I wrote to check bulk statuses. This would also give you a clue on where you are in preorder line.
This script is intended to be used to check your order status only. Please note that this comes with absolutely no warranty and I can't be held responsible for the misuse of the script. AT&T may change their query mechanism if they know about this exploit.
#!/usr/bin/env ruby
require 'rubygems'
require 'open-uri'
require 'openssl'
# FIXME (2008-07-24, praveen): This is nasty. I don't know of any other
# simpler way to skip SSL certificate verification.
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
class Order
attr_reader :order_number, :zip_code, :valid, :canceled, \
:customer_name, :order_date, :shipped, :ship_date, :ship_carrier, \
:tracking_number
def initialize order_number, zip_code
@order_number = order_number
@zip_code = zip_code
@valid = false
@canceled = false
order_status_uri = URI.parse "https://www.wireless.att.com/order_status/\
order_status_results.jsp?fromwhere=order_status&vMethod=ordernum&\
vNumber=#{order_number}&ZipCode=#{zip_code}&x=40&y=14"
order_status = order_status_uri.read
if !order_status.scan("We're sorry, but the information you entered \
was not recognized by our systems.").to_s.empty?
@valid = false
return
end
@valid = true
if !order_status.scan("Canceled")[0].to_s.empty?
@canceled = true
return
end
@canceled = false
@customer_name =
order_status.scan(/Customer:\s*\w*/).to_s.gsub!(/Customer:\s*/,"")
@order_date =
order_status.scan(/Date Ordered:.*/).to_s.gsub!(/Date Ordered:\s*/, "")
@order_date.gsub!(/\s/, "")
@shipped =
order_status.scan(/\<td width="5%".*/)[3].scan(/[01]/).to_s.to_i == 1 ?
true : false
if !@shipped
return
end
@ship_date = order_status.scan(/\<td width="6%".*/)[5]
@ship_date.gsub! /^.*\<p\>/, ""
@ship_date.gsub! /\<\/p\>.*$/, ""
@ship_carrier = order_status.scan(/\<td width="6%".*/)[7]
@ship_carrier.gsub! /^.*\<p\>/, ""
@ship_carrier.gsub! /\<\/p\>.*$/, ""
@tracking_number =
order_status.scan(/\http:\/\/fedex.com\/Tracking\?tracknumbers=\d*/).to_s
@tracking_number.gsub! /\http:\/\/fedex.com\/Tracking\?tracknumbers=/, ""
end
def print
if !@valid
puts "#{@order_number.ljust(6)} ------------------------ NOT FOUND \
------------------------"
return
end
if @canceled
puts "#{@order_number.ljust(6)} ------------------------ CANCELLED \
------------------------"
return
end
if @shipped
puts "#{@order_number.ljust(6)} #{@customer_name.slice(0..14).ljust(15)} \
#{@order_date} #{'Yes'.ljust(5)} #{@ship_date} #{@ship_carrier.ljust(6)} \
#{@tracking_number}"
else
puts "#{@order_number.ljust(6)} #{@customer_name.slice(0..14).ljust(15)} \
#{@order_date} #{'No'.ljust(5)} #{'NA'.ljust(8)} #{'NA'.ljust(6)} \
#{'NA'.ljust(12)}"
end
end
end
if ARGV.length != 3
puts "Usage: ./order-status.rb ZIP BEGIN END
ZIP ZIP code of the AT&T store where the order is placed.
BEGIN Order number to begin searching for.
END Order number to end searching for.
Example: ./order-status.rb 94025 12000 12100
"
else
puts "Que Order# #{'Name'.ljust(15)} Order Dt Ship? Ship Dt Carrie Tracking"
puts "----------------------------------------------------------------------"
queue = 0
for order_number in ARGV[1]..ARGV[2]
o = Order.new order_number, ARGV[0]
if o.valid and !o.canceled
queue += 1 if !o.shipped
display_queue = o.shipped ? "NA" : queue
else
display_queue = "NA"
end
print "#{display_queue.to_s.ljust(3)} "
o.print
end
end
Sample Output
Data is scrambled to protect identity.
praveen@athena:~/scratch/ruby$ ./order-status.rb [ZIP] XX208 XX250 ./order-status.rb:9: warning: already initialized constant VERIFY_PEER Que Order# Name Order Dt Ship? Ship Dt Carrie Tracking ---------------------------------------------------------------------- NA XX208 ***IVEL 07/15/08 Yes 07/18/08 F 981870058XXX 1 XX209 ***EPHINE 07/15/08 No NA NA NA 2 XX210 ***PBELL 07/15/08 No NA NA NA 3 XX211 ***ISSA 07/15/08 No NA NA NA NA XX212 ------------------------ NOT FOUND ------------------------ NA XX213 ***N 07/15/08 Yes 07/18/08 F 981870063XXX NA XX214 ***E 07/15/08 Yes 07/18/08 FDE11 978403293XXX 4 XX215 ***DIRI 07/15/08 No NA NA NA NA XX216 ***TT 07/15/08 Yes 07/24/08 F 981871193XXX 5 XX217 ***E 07/15/08 No NA NA NA 6 XX218 ***TT 07/15/08 No NA NA NA 7 XX219 ***ESH 07/15/08 No NA NA NA 8 XX220 ***D 07/15/08 No NA NA NA 9 XX221 ***ECCA 07/15/08 No NA NA NA 10 XX222 ***ENIA 07/15/08 No NA NA NA NA XX223 ***TEH 07/15/08 Yes 07/18/08 F 981870054XXX 11 XX224 ***TER 07/15/08 No NA NA NA NA XX225 ***TER 07/15/08 Yes 07/24/08 F 981847797XXX NA XX226 ------------------------ CANCELLED ------------------------ NA XX227 ***DA 07/16/08 Yes 07/24/08 FDE51 982002804XXX NA XX228 ------------------------ CANCELLED ------------------------ NA XX229 ***HEESH 07/16/08 Yes 07/18/08 F 981846745XXX 12 XX230 ***ER 07/16/08 No NA NA NA 13 XX231 ***A 07/16/08 No NA NA NA 14 XX232 ***EL 07/16/08 No NA NA NA 15 XX233 ***SWORTH 07/16/08 No NA NA NA 16 XX234 ***SWORTH 07/16/08 No NA NA NA 17 XX235 ***SWORTH 07/16/08 No NA NA NA 18 XX236 ***RGE 07/16/08 No NA NA NA 19 XX237 ***AB 07/16/08 No NA NA NA 20 XX238 ***QUIEL 07/16/08 No NA NA NA NA XX239 ***RY 07/16/08 Yes 07/18/08 F 981870059XXX
Credit: The credit also goes to an anonymous guy who wrote a similar script that I came across in a forum (I forgot the exact place). Most of the regexp ideas were shamelessly stolen from his original script. This is my first non-trivial Ruby script. I don't know much about Ruby. This was a learning script as well. Please bear with newbie mistakes and coding conventions. If you have any comments on the code, I will be more than happy to hear from you.
Update (2008-07-29): AT&T finally decided to do something about the vulnerability. They are using "Captcha" now. So, this script might not work anymore. However I am pretty close to the head of the queue. I might get my phone in a couple of days or so. So, I don't worry about this anymore...
Update (2008-08-02): My phone shipped today.