Skip to content

Automating the tedious task of adding every offer in your account

License

Notifications You must be signed in to change notification settings

constructorfleet/chase-offers

Repository files navigation

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads CircleCI Coverage Discord Backers on Open Collective Sponsors on Open Collective Support us

Description

Many credit card providers provide optional offers (extra points, cash back, etc.) but they require you to log in to your account and manually activate them. This application utilizes YAML configuration files to customize it for nearly any use case. The configuration consists of 3 types:

  • app - Defines the browser's data directory, the users, and accounts that should be processed.
  • user - Defines user's data, including which accounts they apply to and the credentials.
  • account - Defines the steps necessary to activate your offers.

Installation

$ npm install

You will also need to download the chrome-driver off of selenium's site.

Running the app

# development
$ npm run start

# watch mode
$ npm run start:dev

# production mode
$ npm run start:prod

Configuration

The configuration is fully type-safe, if you provide an invalid value or config, it will tell you exactly where and what is invalid.

The configuration files are expected to follow this structure (though you are welcome to change the directories in app.module.ts):

config/
  app.yaml
  users/
    user1.yaml
    user2.yaml
    ...
  accounts/
    account1.yaml
    account2.yaml
    ...

App

userDataDirectory: $PATH_TO_DAT_DIRECTORY # Non-empty path-like string
users:
  - $USER_PROFILE_ID # Non-empty string
  - ...
accounts:
  - $ACCOUNT_NAME # None-empty string
  - ...

User

#user_id1.yaml
id: user_id1 # Non-empty string
accounts:
  - type: account_name_1
    credentials:
      type: basic # TOTP Credentials are on the TODO list
      username: my_username # Non-empty string
      password: my_password # Non-empty string

Account

#account_name_1.yaml
id: account_name1 # Non-empty string
url: http://some.url.com # URL
steps:
  -  # See Steps Section

Steps

There are 3 types of steps:

single - Performs actions on the selected element(s) forEach - Performs actions on the selected element(s) then loops over a range of steps whileFound - Performs actions on the selected elements(s) then continually performs the child steps until the element is not found

type: single # One of the above types
name: Some description for logs # Non-empty string
timeout: 1000 # Integer, defaults to 5000
selector: { See Selector Below }
type: forEach  # One of the above types
name: Some description for logs  # Non-empty string
timeout: 1000  # Integer, defaults to 5000
selector: {See Selector Below}
indexVariable: loopIndex  # Non-empty string to store the current index
loopCountVariable: loopCount  # Non-empty variable-path string to the variable containing the iteration count
selector: {See Selector below}
forEach:  # List of steps to perform on each iteration
type: whileFound  # One of the above types
name: Some description for logs  # Non-empty string
timeout: 1000  # Integer, defaults to 5000
selector: {See Selector Below}
indexVariable: loopIndex  # Non-empty string to store the current index
count
selector: {See Selector below}
whileFound:  # List of steps to perform until the element is not found

Selector

selector:
  cssSelector: "div.id > div > a:nth-child({index})" # Non-empty css-selector string
  isOptional: false # Boolean, if true will skip if not found, defaults to false
  select: all # all or first, determines whether to select all matching elements or the first
  templateReplacers: # Optional map of replacer strings to be replaced with variables in the cssSelector
    "{index}": loopIndex
  shadowRootCSSSelector: "div.btn" # Optional css selector string for an element that is within the shadowRoot of the element found by the cssSelector field
  iFrameSelector: "iframe#logon" # Optional css selector to an iFrame that should be focused before locating elements
  actions: { See Actions } # List of actions to be performed on the element(s) found by the selector

Actions

type: click
type: sendkeys
send: password # Must be 'otp', 'username', 'password' or 'variable - if variable, must provide variablePath
variablePath: chase.cards.1.name # Variable path that has the value that should be send as text to the element
type: count
templateReplacers: # Replacer text to variable paths to replace in the storeUnder field
storeUnder: chase.cards # Variable path to store the count of elements returned by the selector
variableName: count # The name of the variable to store the count - this would yield { chase: { cards: { count: 5 }}}
type: text
templateReplacers:  # Replacer text to variable paths to replace in the storeUnder field
storeUnder: chase.cards  # Variable path to store the count of elements returned by the selector
regexCaptureGroups:  # Map of variable name to the regex to extract the value
  offerName: "^[^,]+"  # This would be stored as
variableName: offers  # The key to store the element's text or the captured groups, this would yield { chase: { cards: {offers: { offerName: "blah" }}}}
templateReplacers:  # Like the selector field, however can be used to dynamically populate variables in the `storeUnder`

Support

This project is MIT-licenced open source. Feel free to use it or not - but if you need support you're probably on your own. Feel free to submit PRs or report bugs and eventually I might get around to those.

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.

Stay in touch

License

Nest is MIT licensed.

About

Automating the tedious task of adding every offer in your account

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published