Coder Social home page Coder Social logo

21bruce / resolved-bot Goto Github PK

View Code? Open in Web Editor NEW
39.0 4.0 10.0 4.44 MB

Resolved is a resy bot that assists in obtaining difficult or high-end reservations. Although it only works with resy, there is an opentable api in the tree.

License: BSD 3-Clause "New" or "Revised" License

Go 100.00%
bot go reservation reservations resy booking opentable resy-bot opentable-bot

resolved-bot's Introduction

resolved-bot

IMPORTANT UPDATE

We currently have no plans to keep the bot up to date, and it is probably not functional. All proposed diffs and patches from the community will still be actively reviewed however.

Description

Resolved is a combination of the following:

  1. A go API to resy
  2. An application on top of the API that can perform concurrent tasks such as repeating a reservation request at differing time intervals or scheduling a reservation request until a specified reservation drop date
  3. A command prompt interface to the application
  4. An HTTP server interface to the application

So far, items 1-3 are implemented, with future plans in the issues section labelled "enhancements"

Steps to build:

  1. Install the go programming language, this can be done by searching "golang installation"
  2. clone this repository
  3. run go build in root directory of project

If you would like to test new features, the develop branch is a decently tested staging area for new feautres, usually 3 features ahead of main.

How to use:

On a successful start up, one should be prompted with the CLI welcome message: prompt

Typing help yields: help

I'll explain each command, but not in the order they appear:

  1. search takes in one required input, the name of restuarant you want to search for, and one optional input, a number to limit the results by. The name of the restaurant is specified with the -n flag(or alternatively the --name flag) and the limit is specified with the -l(alternatively --limit) flag.

Here is an example use of a search using a name of carbone and limit of 5: search

What if the restaurant name has spaces? Just wrap it in square brackets. In this next example, we'll search for "double chicken please":

search_bracket

The purpose of searching is to obtain the VenueID. This number is a unique identifier that resy uses to find the restaurant that you want to reserve at, since multiple restaurants can have the same name.

  1. login takes in two required inputs, the email(-e flag) and password(-p flag) associated with your resy login. It then checks to see if these inputs are a valid login to resy. This command is useful if you intend to use any other command that has an email and password, as these will be used as defaults
  2. logout clears the defaults set by a login if you want to erase your credentials from the system
  3. rats is one of the two core function commands of the bot(the other being rais). Its main use is to schedule a time to try to get a reservation at. For example, some restaurants will only release available seating for a given day six days before. So if I want to reserve an 11 PM on the 7th, I have to be one of the lucky few who press "reserve" fast enough on the 1st. rats will automate this task for you.

Here is an example use:

rats

I'll walk through what each flag does:

  1. -v or --venue-id specifies the unique identifier for which we want to make a reservation. We're using double chicken please's id from the search example.
  2. -resD or --reservation-day specifies the day that we want our reservation at in yyyy:mm:dd format. In this case, we're setting the day to be september 7th, 2023
  3. -resT or --reservation-times specifies the military style times we want to make our reservation at in hh:mm format and in order of priority. In this case, we only have one time, but we could list as many times as we want in that area, and if the first n fail, it will try the n+1th
  4. -ps or --party-size specifies the party size, in this case 2 people
  5. -reqD or --request-date specifies the date at which we want to make the request(basically the date we want to press the "reserve" button at). This should be supplied in military time, with format yyyy:mm:dd:hh:mm (year:month:day:hour:minute). In this case, we want to press "reserve" at midnight on september 1st, 2023.
  6. -t or --table is an optional flag that allows the user to specify a priority list of table types. So an example input is -t outdoor dining. The priority of reservations in this case is all times in -resT will be tried in priority order with the first table type specified, then another iteration of all reservation times with a second table type.

Other flags include a -e flag for email and -p for password, but if logged in this is not needed(actually if you are logged in but don't want to use the login credentials you used in the login command, specifying -e and -p flags here will override those credentials for this command) The output of this command on success is an ID number. This can be used in later commands to see the status(whether it failed or succeeded) or to cancel the operation.

  1. rais is one of the two core function commands of the bot(the other being rats). Its main use is to try to make a reservation at a repeating interval.

The inputs are very similiar to rats:

  1. -v or --venue-id specifies the unique identifier for which we want to make a reservation.
  2. -resD or --reservation-day specifies the day that we want our reservation at in yyyy:mm:dd format.
  3. -resT or --reservation-times specifies the military style times we want to make our reservation at in hh:mm format and in order of priority.
  4. -ps or --party-size specifies the party size, in this case 2 people
  5. -i or --interval specifies the interval to repeat on in hh:mm format. So, if we used all the same parameters for the previous example with -i 00:01, then this command would try to make an 11:30 PM reservation at double chicken please for september 7th, 2023, and the bot would perform this request every minute (00 for hour, 01 for minute)
  6. -t or --table is an optional flag that allows the user to specify a priority list of table types. So an example input is -t outdoor dining. The priority of reservations in this case is all times in -resT will be tried in priority order with the first table type specified, then another iteration of all reservation times with a second table type.

Here are the last remaining commands:

  1. cancel takes in a list of ids using the -i flag and tries to cancel the operation associated with each id. In the rats example, the operation has id 0, so calling cancel -i 0 will cancel the rats operation
  2. list takes in no input and outputs a list of each operation's id, its status(failed, succeeded, cancelled, etc.) and the result(error if failed, reservation time if succeeded)
  3. clean takes in a list of ids using the -i flag and will remove the operation information from the system(i.e. it will no longer be displayed from the list command). Operations can only be cleaned once they are no longer in progress.
  4. exit/quit leaves the prompt
  5. help outputs helpful information about each command

How To Contribute

I am open and happy to accept contributions from anyone who wants to offer them. To get started on this, read the Contribution Etiquette post in the issue section of this project, which should be pinned. Another document which might be helpful in getting adjusted to the project is the Architecture Overview issue post, which provides an overhead view to what each part of the codebase does. Generally, any helpful information can be found in the issue section labelled with information. I'm avaialble at [email protected]; feel free to send any questions to that address.

resolved-bot's People

Contributors

21bruce avatar justin-s-wong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

resolved-bot's Issues

[BUG]: Login Crash with no payment account

Is there an existing issue for this bug?

  • I have searched for this issue

Description of the bug

If logging in with an account that does not have payment set up, bot crashes.

Steps to reproduce

Suppose ###EMAIL### and ###PASSWORD### are the email and password of an account with no payment id.

  1. Start resolved
  2. Type "login -e ###EMAIL### -p ###PASSWORD###"

System Specs

Not needed, this will definitely occur on any platform

Additional Context

This can be fixed with a simple if statement in api/resy/api.go I'm busy but someone else might be interested in solving this one ...

[FEATURE]: Early Authentication + api.Time replacement

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

We would like to implement a method for reducing the overhead of reservation-making http transcations by authenticating before the request date. This should reduce the RTT of the reservation operation by 1/4. Since this issue deals with manipulating dates, we find that a replacement of the api.Time abstraction with the go Time pkg.

Planned Solution

The first steps have already been implemented. These involved adding a method to the api interface that allows a consumer of the interface to extract a minimum auth time variable, which details the minimum amount of time a login token is viable for after a call to login. Then from here we analyzed the resy cookies and found that, accounting for a maximum time-zone diff of 24 hours, the resy auth token is viable for a minimum of 6 days. Now, we seek to utilize this abstraction + the specific value for resy to implement early authentication via the following pseudocode restructuring of the reserveAtTime operation function:

REQUESTDATE - MINAUTHDATE = AUTHDATE

if (AUTHDATE < NOW) {
authenticate
sleep till REQUESTDATE
} else {
sleep till AUTHDATE
authenticate
sleep till REQUESTDATE
}

send request

Alternatives

Implementing a function that substracts api.times in a logical manner v.s. replacing api.time. Figured this function would be very complex

Solution Specifics

See planned solution

[BUG]: Crash on no resvervations for a given day

Is there an existing issue for this bug?

  • I have searched for this issue

Description of the bug

When performing a rats or rais command, if the restaurant does not offer reservations on that day(i.e. not open or not available yet), the app crashes

Steps to reproduce

A step by step of this would be pathological and more complex than a simple explanation:

Take any restaurant, and find a day on resy for which they do not have enabled(i.e. a greyed out day). Run a rats or rais command which requests this disabled day from that restaurant.

System Specs

Not needed, this will occur on any system using the app

Additional Context

I believe the issue is that the reserve api function for resy does not check if it received a list of times and immediately begins trying to reserve them. This can be solved with a simple if statement in api/resy/api.go in the reserve function.

[FEATURE]: OpenTable API

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

If a restaurant is only available for reservation on opentable, the app does not work

Planned Solution

Create an Open Table implementation of the API interface

Alternatives

I've thought of creating a new object / application for Open Table specifically since it uses 2-step login, but I believe generalizing the bot's API pkg to represent 2-step login is a good idea.

Solution Specifics

I've already begun dissecting the internals of Open Table's API using postman, still unsure of how to manage logins, but I believe I might be able to introduce semantics for token refreshing so that multiple logins may not be required. This can improve the response times on the resy API as well

[INFO]: Bot will be down for at least three weeks

Information to share

There's been a lot of posting and emailing about more or less the same bug/issue. Initially I thought this bug was related to the most recent changes adding table type selection to the bot, but even reverting to a version from a month ago(which was working perfectly fine), the error persists. This is alarming, since it means that something on Resy's side changed and that's causing the bug. I've done a preliminary analysis using some println debugging and reviewing the API in firefox and I've deduced two possibilities. 1) The API for the config step has changed, I'll perform some analysis on this the next free moment I have. 2) Resy has increased their use of Captcha, and this is blocking the bot. I personally think 2) is more likely than 1). Regardless, I can't look at 1) till I get a break around three weeks from now, so the bot will be non-functional until that time unless a user is curious enough to look at the code.

IF YOU PLAN TO SOLVE THE PROBLEM:
I've taken a quick look at this bug. The network error occurs on line 366 in api/resy/api.go . The status code returned is 500. For anyone whose looked in the source files, this occurs at the config step of the reserve api operation. I checked to make sure the api key in the codebase is still valid and tried adding a user agent header. These didn't fix the issue.

[INFO]: Architecture Overview

Information to share

This is a general note where I'll go over the overhead view of the architecture the codebase uses for new developers.

The codebase consists of three logical "layers".

The basest layer is the API layer. This layer is found in the api/ directory. At the top level is a package called the api package which provides the api interface. This interface specifies the functions each go api to an external reservation service (resy, opentable, etc.) should have in order to plug in to the rest of the codebase. This layer has sublayers representing the implementations of each external api. These can be found in the api/resy/ and api/opentable/ directories on the develop branch. These packages are where the network requests to resy and opentable are made.

One level higher, we have the App or Backend layer, located in the app/ directory. This layer provides a struct called the AppCtx struct, which takes in an(soon to be multiple) api type and uses it to provide the core functionality of the app. This includes scheduling reservation requests to be sent to servers at specific times and monitoring services on an interval to see if reservations have freed up. This layer is where all the concurrency happens.

The top level layer is dubbed the Runnable or Frontend layer located in the runnable/ directory. It acts as a namespace and common interface to front-end wrappers to the App layer. This is where the CLI application lives as a subpackage, and where the HTTP server will eventually live as subpackage.

There are also a few packages that don't fit anywhere into the architecture but just provide some domain-specific functionality. For example, the CLI application uses a cli tokenizer and parser implemented in the cli/ directory / cli top level package.

[FEATURE]: An option to specify table type

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

Right now there is no way to specify table type. If there are multiple table types for the same time on the same day, how will the system know which one to book? It would be great to be able to specify types like 'Indoors', 'Dining Room', 'Outdoors', 'Patio' etc. to make sure to get the right table.

Planned Solution

N/A

Alternatives

N/A

Solution Specifics

N/A

[FEATURE]: Captcha Cracking for Resy API

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

With the increasing prevalence of bot solutions, resy has started using captcha on higher-demand reservations. If this pattern continues, the critical factor in making reservations will most certainly be the ability to complete a captcha. This is a fantastic blessing in disguise. For one, there are well-documented machine learning algorithms which can classify captchas at an extremely high rate. Second, since most of the bots out there are not actively maintained, they'll be completely useless compared to a bot that handles captcha. Third, and even better, an ML captcha system is probably far faster than the vast majority of people trying to solve a captcha.

Despite these opportunities, implementing captcha accurately is tough. We first have to decipher the networking calls, which is pretty hard since we have to create an event in the browser that we can monitor and study, and these captchas are appearing very infrequently. I'd assume they appear on harder reservations, which makes it harder for us to reproduce and test our implementation. Furthermore, once we have the networking calls down, there are a number of captcha tasks. Some involve typing letters and number, some involve selecting photos, others involve checking a box and then moving the mouse in such a way that google thinks a human is behind the IO. We will need algorithms for these separate functions.

Planned Solution

Add the networking checks and calls to resy's reserve function, create a separate top level package for ML stuff.

Alternatives

None really, maybe somehow displaying the captcha to the user in the terminal, but that seems pathological.

Solution Specifics

There are a few papers online about breaking captchas. For analyzing network calls, we'll start with the common firefox/postman method of breaking and then modify if that doesn't work

[FEATURE]: Change AppCtx to handle multiple API objects

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

Now that there are two APIs, the AppCtx object should be improved to allow for multiple API objects and multiplex properly between them. This will affect developers and end-users, as well as any current applications.

Planned Solution

My solution will introduce the ability to register multiple APIs to the AppCtx object, and restructure the semantics of API calls to force them to specify which API to perform scheduling ops on.

Alternatives

I've considered moving the multiplexing to the runnable layer, so like each runnable makes a separate app context for each api, but then that defeats the point of the common api interface almost, plus I wouldn't want to redo multiplexing logic across runnables

Solution Specifics

I'll update this with more specifics in a few days

[BUG]: bot not firing?

Is there an existing issue for this bug?

  • I have searched for this issue

Description of the bug

for some reason the bot doesn't seem to be working. I put 3 requests in, two of which have passed and should have fired. yet when I request a list, it says all three are still in progress.
Screenshot 2024-02-17 at 3 16 44 PM

Steps to reproduce

I used semma and via carota as the two restaurants, filled in reqD of 2.15 and 2.17 at midnight. now 3pm on 2.17 and neither have fired.

System Specs

macos ventura

Additional Context

No response

[BUG]: Unknown Network Error

Is there an existing issue for this bug?

  • I have searched for this issue

Description of the bug

Screenshot 2024-03-04 132324
After bot is firing I am getting an unknown network error.
I am using this version 60e88dd

Steps to reproduce

I am just running a rats command and after the time hits for the request date and I run the list command I am getting an unknown network error. I have tested with a few different venue IDs.
rats -v XXXX-resD 2024:03:13 -resT 20:00 -ps 2 -reqD 2024:03:04:13:10

System Specs

Windows - Git Bash

Additional Context

No response

[BUG]: "unknown network error" when attempting to get reservation

Is there an existing issue for this bug?

  • I have searched for this issue

Description of the bug

When attempting to get a reservation (e.g. rats -v 2038 -resD 2024:02:18 -resT 20:00 -ps 2 -reqD 2024:02:07:22:2), the attempt fails and the result is "unknown network error"

Steps to reproduce

  1. Create reservation request via the rats command
  2. Wait for the reqD time to pass

System Specs

N/A

Additional Context

No response

[INFO]: Documentation Etiquette

Information to share

In consideration with how long the last PR took to update documentation, I am now enacting a rule for future PRs that documentation is always expected and if not present a good reason must be submitted along with the PR.

General rules for documentation are as follows:

  1. Every pkg should have a doc.go with at least one section titled General Purpose that outlines what the pkg is trying to accomplish. If the pkg has sub-pkgs, then these should also do this, and their doc.go should reference the parent's.
  2. Every file added must have an author statement(including created at date), and every file modified must have a modified statement(including modified at date), with the new contributors name and a summary of what they did in the file
  3. Every function, structure, interface, or any other method of abstracting must have a top-level comment explaining the purpose for the abstraction as well as expected inputs and outputs

[FEATURE]: Improve documentation

Is there an existing issue for this feature?

  • I have searched for this issue

Description of the problem

The codebase needs improved documentation, this affects developers

Planned Solution

I'll just write more documentation on this branch

Alternatives

None this is pretty necessary

Solution Specifics

For each function exported from a package, I'll write a comment describing required inputs and outputs. For each package, I'll include a list of API functions in a doc.go file along with a general purpose statement

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.