Skip to content

Instantly share code, notes, and snippets.

@stormchasing
Last active January 6, 2024 20:53
Show Gist options
  • Save stormchasing/454c92cfc1b9d6f51468 to your computer and use it in GitHub Desktop.
Save stormchasing/454c92cfc1b9d6f51468 to your computer and use it in GitHub Desktop.
Auto Check-In to Southwest Flights.user.js
// ==UserScript==
// @name Auto Check-In to Southwest Flights
// @namespace http://www.ryanizzo.com/southwest-auto-check-in/
// @version 1.8
// @author Nicholas Buroojy (http://userscripts.org/users/83813)
// @contributor Ryan Izzo (http://www.ryanizzo.com)
// @contributor JR Hehnly (http://www.okstorms.com @stormchasing)
// @contributor Trevor McClellan (github.com/trevormcclellan)
// @description Automatically check in to Southwest Airline flights at the appropriate time.
// @include https://www.southwest.com/air/check-in/index.html*
// @include https://www.southwest.com/flight/selectCheckinDocDelivery.html*
// @include https://www.southwest.com/air/check-in/confirmation.html*
// @copyright 2009+, Nicholas Buroojy (http://userscripts.org/users/83813)
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// History
//
// 10/2012 v1.2 Ryan Izzo (ryanizzo.com)
// Updated to use new Southwest Check In page, added validation
//
// 7/2014 v1.3 Ryan Izzo (ryanizzo.com)
// Moved script to GitHub since UserScripts appears dead
//
// 10/2014 v1.4 JR Hehnly (@stormchasing)
// Added phone number entry to auto-text boarding pass docs to mobile device
//
// 3/28/2016 v1.5.1 Trevor McClellan (github.com/trevormcclellan)
// Fixed phone number entry system
//
// 9/2017 v1.6 JR Hehnly (@stormchasing)
// Initial changes to handle new Southwest confirmation lookup page
//
// 10/03/2017 v1.6.1 JR Hehnly (@stormchasing)
// Got the script to a state where check-in works, but no auto-text boarding pass yet.
// Have not determined what event listeners need to be triggered in the phone number form field.
// Submits sucessfully if last phone number character is manually typed, but fails validation if it's only filled by the script.
//
// 3/02/2018 v1.7 JR Hehnly (@stormchasing)
// Messy update to get this working somewhat reliably again.
// Removed the 'text boarding pass' feature that wasn't working
// Increased default start second from 02 to 04 since Southwest would complain about 'outside the 24 hour check-in window' when using 02
//
// 8/23/2019 v1.8 JR Hehnly (@stormchasing)
// Adjusted default seconds to :07
// Verified working with this setting
// General code cleanup
//
// TODO: Use Southwest's server's time instead of the client's clock.
// TODO: Test select passenger page.
const DEFAULT_SECONDS = '07';
///////////// CHECK IN PAGE ////////////////
let globalSubmitDate;
let allDone = false;
/**
* @brief Submit the check in form on the Southwest Check In Online page.
*/
function submitNow()
{
try{
let submitButton = document.getElementById("form-mixin--submit-button");
submitButton.click();
}
catch(e){
alert('globalSubmitDate: An error has occurred: '+ e.message);
}
}
/**
* @brief Display the countdown.
*
* TODO: Some formatting is wrong eg ("1:0:12" means 1 hour and 12 seconds remain). Make sure everything is represented with 2 digits.
*/
function displayCountdown()
{
try{
let area = document.getElementById("countdown");
let timeRemain = globalSubmitDate - new Date();
let days = Math.floor(timeRemain / (1000 * 60 * 60 * 24));
let hours = Math.floor(timeRemain / (1000 * 60 * 60)) % 24;
let minutes = Math.floor(timeRemain / (1000 * 60)) % 60;
//round to the nearest second
let seconds = Math.round(timeRemain / 1000) % 60;
//Don't print negative time.
if (hours < 0 || minutes < 0 || seconds < 0)
{
area.innerHTML = "Checking In...";
return;
}
area.innerHTML = "Time Remaining: <strong>";
//If 0 days remain, omit them.
if (days !== 0)
area.innerHTML += days + "d ";
//If 0 hours remain, omit them.
if (hours !== 0)
area.innerHTML += hours + "h ";
//Add padding to minute
if (minutes !==0 )
//area.innerHTML += "0";
area.innerHTML += minutes + "m ";
//Add padding to second
//if (seconds < 10)
//area.innerHTML += "0";
area.innerHTML += seconds;
area.innerHTML += "s</strong>";
}
catch(e){
// has the page changed?
if(/review/.test(document.location.href))
{
autoPassengerPage();
return;
}
else if(/confirmation/.test(document.location.href))
{
if (allDone === false)
{
//autoTextBoardingDocs();
}
return;
}
console.log('displayCountdown: An error has occurred: ' +e.message);
}
}
/**
* @brief Updates the countdown every second.
*/
function displayCountdownWrapper()
{
try{
window.setInterval(displayCountdown, 1000);
}
catch(e){
console.log('displayCountdownWrapper:" An error has occurred: ' +e.message);
}
}
/**
* @brief Begins the delay at the next even second.
*/
function beginDelay()
{
try{
let confNumber = document.getElementById("confirmationNumber").value;
let firstName = document.getElementById("passengerFirstName").value;
let lastName = document.getElementById("passengerLastName").value;
let month = document.getElementById("month-input").value;
let day = document.getElementById("day-input").value;
let year = document.getElementById("year-input").value;
let hour = document.getElementById("hour-input").value;
let minute = document.getElementById("minute-input").value;
let second = document.getElementById("second-input").value;
// let phoneArea = document.getElementById("phoneArea").value;
// let phonePrefix = document.getElementById("phonePrefix").value;
// let phoneNumber = document.getElementById("phoneNumber").value;
if(confNumber === "" || firstName === "" || lastName === "" ){
alert("Must fill out Confirmation Number and Name.");
}
else if(month === "" || month === "mm" || day === "" || day == "dd" || year === "" || year == "yyyy" ||
hour === "" || hour == "hh" || minute === "" || minute == "mm" || second === "" ){
alert("Must fill out Date and Time.");
}
else if(year.length < 4 ){
alert("Year must be 4 characters.");
}
// else if (phoneArea.search(/\d\d\d/g) == -1 || phonePrefix.search(/\d\d\d/g) == -1 || phoneNumber.search(/\d\d\d\d/g) == -1) {
// alert("Invalid phone number provided.");
// }
else{
// //save the text number for later
// GM_setValue("phoneArea", phoneArea);
// GM_setValue("phonePrefix", phonePrefix);
// GM_setValue("phoneNumber", phoneNumber);
//Build a date
let submitDate = new Date();
//submitDate.setMonth(month - 1);
//submitDate.setDate(day);
submitDate.setFullYear(year, month - 1, day);
submitDate.setHours(hour);
submitDate.setMinutes(minute);
submitDate.setSeconds(second);
submitDate.setMilliseconds(0);
let now = new Date();
let msRemaining = submitDate - now;
let maxDays = 14;
if(msRemaining < 0)
alert("Date/Time must be in the future.");
else if(msRemaining > maxDays * 1000 * 60 * 60 * 24)
alert("Date/Time cannot be more than " + maxDays + " days in the future." + msRemaining);
else{
//Install the timeout to submit the form.
window.setTimeout(submitNow, msRemaining);
globalSubmitDate = submitDate;
//Install a short term timeout to call the countdown wrapper at the beginning of the next second.
window.setTimeout(displayCountdownWrapper, msRemaining % 1000);
}
}
}
catch(e){
console.log('beginDelay: An error has occurred: '+ e.message);
}
}
/**
* @brief Edits the check in page; Adds Date, time, and Auto Check In button
*
* TODO Error handling. (Auto notify the developer when southwest page changes)
*/
function checkInPageFormEdit()
{
try{
let leftPanel = document.getElementsByClassName("air-reservation-confirmation-number-search-form")[0];
//All of our stuff will go in this div.
let delayDiv = document.createElement("div");
delayDiv.setAttribute('id','checkInDelay');
let dateSelect = document.createElement("span");
dateSelect.setAttribute('id','date-select');
//The big label at the top of the menu
let mainLabel = document.createElement("h4");
mainLabel.setAttribute('class','swa_feature_checkInOnline_form_header');
mainLabel.innerHTML = "Set Check In Date and Time";
dateSelect.innerHTML += "<br/>";
dateSelect.appendChild(mainLabel);
//The date portion.
let today = new Date();
let dateLabel = document.createElement("label");
dateLabel.innerHTML = "<span class=\"required\">*</span> Date:";
let monthInput = document.createElement("input");
monthInput.setAttribute('id','month-input');
monthInput.setAttribute('type','text');
monthInput.setAttribute('maxlength','2');
monthInput.setAttribute('size','2');
monthInput.setAttribute('value', (today.getMonth()+1).toString());
monthInput.setAttribute('onfocus','if(this.value==\'mm\') this.value=\'\';');
monthInput.setAttribute('style','margin-left:7em');
monthInput.setAttribute('tabindex','5');
let dayInput = document.createElement("input");
dayInput.setAttribute('id','day-input');
dayInput.setAttribute('type','text');
dayInput.setAttribute('maxlength','2');
dayInput.setAttribute('size','2');
dayInput.setAttribute('value', today.getDate().toString());
dayInput.setAttribute('onfocus','if(this.value==\'dd\') this.value=\'\';');
dayInput.setAttribute('tabindex','6');
let yearInput = document.createElement("input");
yearInput.setAttribute('id','year-input');
yearInput.setAttribute('type','text');
yearInput.setAttribute('maxlength','4');
yearInput.setAttribute('size','4');
yearInput.setAttribute('value', today.getFullYear().toString());
yearInput.setAttribute('onfocus','if(this.value==\'yyyy\') this.value=\'\';');
yearInput.setAttribute('tabindex','7');
dateSelect.appendChild(dateLabel);
dateSelect.appendChild(monthInput);
dateSelect.innerHTML += "/";
dateSelect.appendChild(dayInput);
dateSelect.innerHTML += "/";
dateSelect.appendChild(yearInput);
// The time portion.
let timeLabel = document.createElement("label");
timeLabel.innerHTML = "<span class=\"required\">*</span> Time: (24-hour format) ";
let hourInput = document.createElement("input");
hourInput.setAttribute('id','hour-input');
hourInput.setAttribute('type','text');
hourInput.setAttribute('maxlength','2');
//hourInput.setAttribute('style','margin-left:10px');
hourInput.setAttribute('size','2');
hourInput.setAttribute('value', today.getHours().toString());
hourInput.setAttribute('onfocus','if(this.value==\'hh\') this.value=\'\';');
hourInput.setAttribute('tabindex','8');
let minuteInput = document.createElement("input");
minuteInput.setAttribute('id','minute-input');
minuteInput.setAttribute('type','text');
minuteInput.setAttribute('maxlength','2');
minuteInput.setAttribute('size','2');
minuteInput.setAttribute('value', today.getMinutes().toString());
minuteInput.setAttribute('onfocus','if(this.value==\'mm\') this.value=\'\';');
minuteInput.setAttribute('tabindex','9');
let secondInput = document.createElement("input");
secondInput.setAttribute('id','second-input');
secondInput.setAttribute('type','text');
secondInput.setAttribute('maxlength','2');
secondInput.setAttribute('size','2');
secondInput.setAttribute('value', DEFAULT_SECONDS);
secondInput.setAttribute('tabindex','10');
dateSelect.innerHTML += "<br/><br/>";
dateSelect.appendChild(timeLabel);
dateSelect.appendChild(hourInput);
dateSelect.innerHTML += ":";
dateSelect.appendChild(minuteInput);
dateSelect.innerHTML += ":";
dateSelect.appendChild(secondInput);
delayDiv.appendChild(dateSelect);
//auto-text boarding pass section
// let autoTextArea = document.createElement("div");
// let textLabel = document.createElement("label");
// textLabel.innerHTML = "<span class=\"required\">*</span> Boarding pass text number: ";
//
// let phoneArea = document.createElement("input");
// phoneArea.setAttribute('id','phoneArea');
// phoneArea.setAttribute('type','text');
// phoneArea.setAttribute('maxlength','3');
// phoneArea.setAttribute('size','3');
// phoneArea.setAttribute('value', GM_getValue("phoneArea") !== undefined ? GM_getValue("phoneArea") : '');
// phoneArea.setAttribute('tabindex','12');
//
// let phonePrefix = document.createElement("input");
// phonePrefix.setAttribute('id','phonePrefix');
// phonePrefix.setAttribute('type','text');
// phonePrefix.setAttribute('maxlength','3');
// phonePrefix.setAttribute('size','3');
// phonePrefix.setAttribute('value', GM_getValue("phonePrefix") !== undefined ? GM_getValue("phonePrefix") : '');
// phonePrefix.setAttribute('tabindex','13');
//
// let phoneNumber = document.createElement("input");
// phoneNumber.setAttribute('id','phoneNumber');
// phoneNumber.setAttribute('type','text');
// phoneNumber.setAttribute('maxlength','4');
// phoneNumber.setAttribute('size','4');
// phoneNumber.setAttribute('value', GM_getValue("phoneNumber") !== undefined ? GM_getValue("phoneNumber") : '');
// phoneNumber.setAttribute('tabindex','14');
//
// autoTextArea.innerHTML += "<br/>";
//
// autoTextArea.appendChild(textLabel);
// autoTextArea.innerHTML += "(";
// autoTextArea.appendChild(phoneArea);
// autoTextArea.innerHTML += ")";
// autoTextArea.appendChild(phonePrefix);
// autoTextArea.innerHTML += "-";
// autoTextArea.appendChild(phoneNumber);
//
// delayDiv.appendChild(autoTextArea);
//
delayDiv.innerHTML += "<br/><br />";
// The area that displays how much time remains before the form is submitted.
let countdownArea = document.createElement("div");
countdownArea.setAttribute('id','countdown');
countdownArea.innerHTML = "Click to start countdown";
delayDiv.appendChild(countdownArea);
// Auto Check In button
let delayButton = document.createElement("input");
delayButton.setAttribute('id','delay-button');
delayButton.setAttribute('type','button');
delayButton.setAttribute('style','float: right; background-color: #FFBF27; color: #111B40: font: bold 17px/1 Arial');
delayButton.setAttribute('value','Auto Check In');
delayButton.addEventListener("click", beginDelay, true);
delayButton.setAttribute('tabindex','11');
delayDiv.appendChild(delayButton);
leftPanel.appendChild(delayDiv);
}
catch(e){
console.log('checkInPageFormEdit: An error has occurred: ' +e.message);
}
}
///////////// SELECT PASSENGER PAGE ////////////////
//automatically select all passengers and submit the form
function autoPassengerPage()
{
try{
//find error notification
if(document.title == "Error")
return;
// Check all the check boxes.
let node_list = document.getElementsByTagName('input');
for (let i = 0; i < node_list.length; i++) {
let node = node_list[i];
if (node.getAttribute('type') == 'checkbox') {
node.checked = true;
}
}
//Click the print button
let button = document.getElementsByClassName("actionable actionable_button actionable_large-button actionable_no-outline actionable_primary button submit-button air-check-in-review-results--check-in-button")[0];
button.click();
}
catch(e){
console.log('autoPassengerPage: An error has occurred: '+ e.message);
}
}
///////////// BOARDING DOC DELIVERY PAGE ////////////////
//function autoTextBoardingDocs()
//{
// try{
// //find error notification
// if (document.title == "Error")
// return;
//
// //click the Text button
// let button = document.getElementsByClassName("actionable actionable_button actionable_full-width actionable_large-button actionable_no-outline actionable_prefix actionable_secondary-dark-affix button boarding-pass-options--button-text")[0];
// button.click();
// window.setTimeout(waitForSendButton, 500);
// }
// catch(e){
// alert('autoTextBoardingDocs: An error has occurred: '+ e.message);
// }
//}
//
//function waitForTextBoardingPass() {
// if(document.getElementById("textBoardingPass") === null) {
// window.setTimeout(waitForTextBoardingPass, 100);
// } else {
// document.getElementById("textBoardingPass").focus();
// document.getElementById("textBoardingPass").value = parseInt(GM_getValue("phoneArea") + GM_getValue("phonePrefix") + GM_getValue("phoneNumber"));
// waitForSendButton();
// }
//}
//
//function waitForSendButton() {
// if(document.getElementById("form-mixin--submit-button") === null || document.getElementById("textBoardingPass").value != GM_getValue("phoneArea") + GM_getValue("phonePrefix") + GM_getValue("phoneNumber")) {
// document.getElementById("textBoardingPass").focus();
// document.getElementById("textBoardingPass").value = parseInt(GM_getValue("phoneArea") + GM_getValue("phonePrefix") + GM_getValue("phoneNumber"));
// window.setTimeout(waitForSendButton, 100);
// } else {
// //document.getElementById("form-mixin--submit-button").focus();
// //document.getElementById("form-mixin--submit-button").click();
// allDone = true;
// }
//}
//case of the select boarding pass page (regex match the url)
if(/review/.test(document.location.href))
{
autoPassengerPage();
}
//case of the check in page
else if(/index/.test(document.location.href))
{
checkInPageFormEdit();
}
//else if(/confirmation/.test(document.location.href))
//{
// autoTextBoardingDocs();
//}
@dwightmulcahy
Copy link

I tried this the other day with 4, 6, 8 seconds and all of them failed with "Online Check-In Not Available". Does this not work anymore?

@crazycorkey
Copy link

@stormchasing I got the same error as @dwightmalcahy but it I know it was definitely after the check in time because the error timestamp was 1 second before my auto check in (4 seconds post allowed check in), so it must be server time. They must have implemented something new or the submitDate is broken.

Online check-in not valid at this time.
You're requesting to check in and print your boarding pass outside our permitted 24 hour check-in window. Please check in within 24 hours of your flight's scheduled departure.
Error details
Error detail 1: RbuHin84SqiDNTRvbgEl6g : 4c53bd61-2c35-4ea5-ae26-98d93652b9ee : 40030610807/28/2018 - 21:50:03

@danshaw
Copy link

danshaw commented Jul 31, 2018

I think its just that you guys are putting in a time that is too soon. I've noticed that if I choose 30 seconds it works fine. It doesn't work for anytime earlier. So that means that the Southwest server is either 30 seconds behind or my computer is 30 seconds ahead.

The last couple of flights I have opened 3 tabs and set the time for 10 seconds apart. The first two failed at 10 and 20 seconds after check-in time.

I would be nice to know what the Southwest server time is, but as of right now, this has solved it for me.

@jheezy925
Copy link

@danshaw, if we are using 30 seconds, you can check in manually faster than that but I guess the whole point of this script is to auto-check in for you if you forgot to.

@honeytrek
Copy link

honeytrek commented Aug 5, 2018

UPDATE: I tried mutliple times and it wouldn't work. I finally got it to work by doing a CTRL-F5 refresh and it finally showed up.


Anyone else having issues getting this set up? I have the full 492 lines of code in Tampermonkey. Go to the check in screen, enter a valid Confirmation code for a flight this tuesday, first and last name, and don't get the screen shown in the instructions.

Would love any insights. Thanks guys,
Mike

@simplemark
Copy link

Worked for me on Chrome incognito tab, after I refreshed the page. To create additional pages, I had to copy and paste the URL to the next tab, otherwise script wouldn't work and the additional fields didn't show up, even with hard refresh...not sure why. I could not get it to work on FIrefox.

@Jeremyyang920
Copy link

So the script works, but Southwest's website is actually delayed by a few seconds. Even on my other laptop, when I tried pressing check-in 5 seconds later, it would tell me that I couldn't check in since it was still more than 24 hours out. Seems the site was around 7-10 seconds slower than true clock time.

@greg7snyder
Copy link

I got everything installed correctly and succeeded at getting the countdown clock. I'm new to scripts though so I have one key question:

Do I need to keep the tab open and my computer on for the script to work at the appointed time?

@jgoggan
Copy link

jgoggan commented Sep 12, 2018

Do I need to keep the tab open and my computer on for the script to work at the appointed time?

Yes. You need to leave it open/running.

@greg7snyder
Copy link

Thank you

@andrewjs18
Copy link

has anyone ran this from a server rather than through their browser? if so, are there any tutorials available?!

@ejcrotty
Copy link

My understanding is that every attempt to do this NOT from a browser would get blocked by southwest. Since this is indistinguishable from a vanilla browser to Southwest, they have no way to block it. It does work great, as long as your internet is up ( found that out the hard way )

@crazycorkey
Copy link

@stormchasing I got the same error as @dwightmalcahy but it I know it was definitely after the check in time because the error timestamp was 1 second before my auto check in (4 seconds post allowed check in), so it must be server time. They must have implemented something new or the submitDate is broken.

Online check-in not valid at this time.
You're requesting to check in and print your boarding pass outside our permitted 24 hour check-in window. Please check in within 24 hours of your flight's scheduled departure.
Error details
Error detail 1: RbuHin84SqiDNTRvbgEl6g : 4c53bd61-2c35-4ea5-ae26-98d93652b9ee : 40030610807/28/2018 - 21:50:03

@stormchasing sorry before, it does indeed work still, just was cutting the time too close. One area that could be improved is on international flights after the original submit page it asks for emergency contact info. The script needs to select a No Thanks button and then a new Check In button. You can pre-enter Passport Info but I haven't seen how to pre-enter emergency contact info so it doesn't ask. If Visa info was required that would be a whole other thing, but luckily not needed for Mexico flights.

@tjs198
Copy link

tjs198 commented Dec 31, 2018

@crazycorkey - you can fill in the emergency contact info here: https://www.southwest.com/air/manage-reservation/index.html

@dmwyatt
Copy link

dmwyatt commented Jan 11, 2019

FYI, I used this today and it worked at 5 seconds.

@RipVanW
Copy link

RipVanW commented Jan 13, 2019

I used this today and I had multiple incognito Chrome windows set up. I started at :00, which returned an error that said :54 (six sec before my allowed check-in time). It returned errors for :02, :04, :05, :06, :07, :08 and :10. I had also set up a window at :15, which I thought would be way past my check-in time, but it checked me in. The timestamp of the errors went up by 2 sec each time, and I thought it was interesting that at 10 full sec past my allowed check in time the error that came back was stamped :04. So my computer is 6 sec fast or whatever, but even if it is, why isn't the SWA computer letting me check in after my allowed time?

@trizzz1327
Copy link

Anyone get the auto text boarding pass to work or auto email boarding pass?

@kieths
Copy link

kieths commented Feb 24, 2019

I discovered your script last night (newbie by definition), and installed it into TamperMonkey v4.8.5847 under FireFox Mobile (Firefox v65.0.1, Android 8.1.0, SGN9). There were no script errors, but I didn't get the expected entry asking for date/time, likely since the URL/syntax for mobile is not recognized by the script. The URL for mobile, per FireFox Android is: https://mobile.southwest.com/check-in

For this trip, I opted to install your script into my notebook which is running TamperMonkey v4.8 (Win 10 Pro x64, Google Chrome Version 72.0.3626.109 (Official Build) (64-bit)). The script appeared to run, asking for the target date/time, etc. But when the screen didn't appear to update/refresh within a few seconds after the check-in target scheduled, I manually checked in with the mobile app (patience may have paid off with an auto-checkin, my ISP perhaps had a hiccup, or perhaps the script really did already check-in without refreshing to display the result, it's hard to guess).

Request:
Add URL(s) (syntax differences?) lines to your script as needed to run under Android mobile, for Firefox.
FireFox Android is bulky, but is well maintained, as is TamperMonkey for Android, thus my target.
The ideal solution would be a standalone APK app, but it may be difficult maintaining compatibility with SWA's website(?).

Why a mobile solution? Air travelers are on the fly - mobile. It's not always possible to have a PC running and awaiting the check-in time. Having the script (or app) runnable by mobile, travelers could set it to trigger check in easily for Both directions of the flight while travelling light, not just before initial departure, through their home PC.

@Eibwen
Copy link

Eibwen commented Apr 23, 2019

Some ideas/suggestions:

  • At the scheduled time, have it push the button and detect if the little error message shows up, and retry every 5 seconds after the time hits if its still on the check-in page?
  • I would think you should be able to use this page and related to automatically determine the check-in time: https://www.southwest.com/air/manage-reservation/index.html, with a fair amount of processing work though, so understandable you're not doing that (unless there is a UTC version of the times displayed on that page, I would expect not, so fairly tricky)
  • Adding an editable div that looks like a textbox, to (optionally) put in text number or email to send the boarding pass to would be a nice to have feature

Regarding @kieths comment above, getting a tampermonkey script like this to work on mobile I don't expect to be reliable. I'd imagine you'd have to keep your phone active AND on the webpage for it to work at all. If the browser goes into the background it will often stop running javascript on the open pages, if its in the background too long the whole browser gets thrown out of memory and mobile apps are often designed to make it not obvious that the app is completely restarting from scratch. So yes, an APK would be a great solution, but quite a bit more work, and very possibly tricky to get into the app store. I don't think its good to install or distribute raw APKs since that would be an easy virus attack vector. If someone made an app (I don't have enough motivation to do so) and got it in the app store, I would 100% use it though.

@tonesjones
Copy link

What's the expected behavior after the countdown reaches 0? I watched it today and nothing happened, i didn't want to risk losing a good seat so i manually clicked check-in and got seats in the A section.

However, what i'm wondering is if I wasn't sitting here watching, should i just expect to come back to my computer and it'll be on the page that shows that you're checked-in without having to click the button or refresh the page?

@jplee3
Copy link

jplee3 commented Jun 11, 2019

Is this broken? I just tried in Chrome Incognito Mode and had several instances up to attempt checking in at different second intervals. All of them kicked off but were hung at "Checking In..." and didn't actually check in. I only got checked in after manually hitting the button and got into the B group...

Copy link

ghost commented Jul 31, 2019

This works. I just used it today successfully.

@ellj
Copy link

ellj commented Sep 2, 2019

Works, used today in Chrome on Mac

@ejcrotty
Copy link

I've had multiple failures in the last few days at :04 ( not available ) , which had been working for me for a long time. Anyone have an idea of what delay is working currently?

@stormchasing
Copy link
Author

I've had multiple failures in the last few days at :04 ( not available ) , which had been working for me for a long time. Anyone have an idea of what delay is working currently?

Latest version is set to 7 seconds by default and has been verified to work.

@ejcrotty
Copy link

ejcrotty commented Nov 7, 2019 via email

@ez12a
Copy link

ez12a commented Nov 7, 2019

Thanks for this! Is it me or does the delay not seem to work? It looks like it just immediately pressed the check in button when the minute turned over without any wait. I got an error and luckily was babysitting it so I could just rehit Check In.

I tried to "check-in" a second time and again, it clicked on Check In immediately.

edit: just realized, i guess it populates the seconds.

@macsouth
Copy link

A 49 for the first leg and A 45 for the second, and I didn't have to wake up at 6:25am to check in! What a game-changer! Thank you so much!

@ejcrotty
Copy link

7 seconds failed for me this morning. Swithching to 9. Ugh

@joshjohanning
Copy link

7 seconds failed for me this morning. Swithching to 9. Ugh

it depends on the system time on your machine, so each machine could be a little different. My machine is :12 seconds

@ejcrotty
Copy link

ejcrotty commented Dec 19, 2019 via email

@joshjohanning
Copy link

But my time syncs to the internet? How can it be different?

On Wed, Dec 18, 2019 at 8:44 PM Joshua Johanning @.***> wrote: 7 seconds failed for me this morning. Swithching to 9. Ugh it depends on the system time on your machine, so each machine could be a little different. My machine is :12 seconds — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://gist.github.com/454c92cfc1b9d6f51468?email_source=notifications&email_token=AFC3CUPCUZ2YA2JNZ76VXDLQZLNZFA5CNFSM4HH4VRZ2YY3PNVWWK3TUL52HS4DFVNDWS43UINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAF6FJO#gistcomment-3115671, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFC3CUJSU7L3C67SR5FJATLQZLNZFANCNFSM4HH4VRZQ .

Different internet sync sources? And perhaps southwest's server times changing slightly too.

@tjs198
Copy link

tjs198 commented Jan 25, 2020

not working for me, hangs up on 'checking in . . .' when timer ends, doesn't appear to actually activate the check-in and doesn't get boarding position

@ltrainpr
Copy link

not working for me either, same as tjs198

@RipVanW
Copy link

RipVanW commented Feb 1, 2020

Still working well for me. I have v 1.7 running on Tampermonkey on Chrome. I set up multiple tabs and it checked me in at :06 past the hour according to my PC clock. I used it yesterday, too, to check someone else in, and that time it used the :08 delay. Thanks for the super handy programming!

@nyknicks8
Copy link

Works nicely

@jacksbetter
Copy link

I've used a version of these scripts in the past with no problems, but now, I can't seem to even get the timer fields to show up when running! I tried refreshing, new tab, and other tries, but still can't even get the input fields to show up with this script active in Tampermonkey Chrome.

@ejcrotty
Copy link

ejcrotty commented Feb 10, 2020 via email

@usafdixon
Copy link

I am new to this type of script. Where do you specify the confirmation number and passengers?

@joshjohanning
Copy link

I am new to this type of script. Where do you specify the confirmation number and passengers?

You navigate to the check in page in your browser, you might have to submit the form once and let it 'fail' in order for you to see the auto check in form.

@knowyourrivals
Copy link

Anyone else still using this successfully? I just tried today, and did not receive a Boarding Pass confirmation message as listed here: https://www.theartoftravelhacking.com/automatic-check-southwest-flights/ , so after a few minutes I went ahead and checked in via the Southwest mobile app, and still received A38 boarding. Not bad, and it could be that this is a low volume flight, or, the script worked and did not give me a confirmation (?).

@RipVanW
Copy link

RipVanW commented Nov 29, 2020

Worked again for me, using the default :04 delay with zero error messages. A50, which is good considering heavy travel around Thanksgiving, even in 2020. I'm still on v1.7--kind of apprehensive about updating since it's working flawlessly for me. I still have to go in to the app or the site and get my boarding pass, but that's no big deal to me. This time I used a standard Chrome window for my :04 delay, and had 4 incognito windows open with +2 sec delays for each. Didn't need them, unlike in the past.

@julesallen
Copy link

Tried to use it to check in today and the initial check in click got triggered on time.

Then on the next page I got this error:

submitNow: An error has occurred: Cannot read properties of null (reading 'click')

I'm a Python programmer so not sure how to debug why submitNow() is triggering on the second page (which should be handled by autoPassengerPage()?).

No errors in the console either.

@wzielicke
Copy link

Today checked in for a US flight
Got the "Submit now. An error has occurred. Cannot read properties of null (reading 'click')

@tjs198
Copy link

tjs198 commented Dec 23, 2022

@julesallen
Copy link

use: https://www.robofly.me/

This site has absolutely nothing on it saying what it does, who they are, and why they should be trusted with access to your Google account.

@kieths
Copy link

kieths commented Apr 21, 2023

RE: 8/23/2019 v1.8 JR Hehnly (@stormchasing), circa 21/April/2023, receiving pop-up error at top of screen:
www.southwest.com says

submitNow: An error has occurred: Cannot read properties of null (reading 'click')

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