From b1b0cc2231aac881da37d7b7303e1b19e42af818 Mon Sep 17 00:00:00 2001 From: Evgeny Svirsky Date: Sat, 11 Nov 2023 07:51:12 +0100 Subject: [PATCH] - initial version --- .env | 3 + .github/workflows/schedule.yaml | 35 ++++ .gitignore | 40 ++++ .nvmrc | 1 + README.md | 14 ++ package-lock.json | 338 ++++++++++++++++++++++++++++++++ package.json | 17 ++ src/checker.ts | 102 ++++++++++ src/index.ts | 9 + src/notifier.ts | 7 + src/vfs-response.type.ts | 7 + tsconfig.json | 26 +++ 12 files changed, 599 insertions(+) create mode 100644 .env create mode 100644 .github/workflows/schedule.yaml create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 README.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/checker.ts create mode 100644 src/index.ts create mode 100644 src/notifier.ts create mode 100644 src/vfs-response.type.ts create mode 100644 tsconfig.json diff --git a/.env b/.env new file mode 100644 index 0000000..9b2055d --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +VFS_GLOBAL_URL=https://lift-api.vfsglobal.com/appointment/CheckIsSlotAvailable +## TO DO: Move to secrets +AUTHENTICATED_TOKEN=AUTHENTICATED_TOKEN diff --git a/.github/workflows/schedule.yaml b/.github/workflows/schedule.yaml new file mode 100644 index 0000000..b49dc0b --- /dev/null +++ b/.github/workflows/schedule.yaml @@ -0,0 +1,35 @@ +name: Execute the script to check VFS global dates +on: + schedule: + - cron: "0 * * * *" # Every hour + workflow_dispatch: + +jobs: + execute_script: + runs-on: [ubuntu-latest] + steps: + - uses: actions/checkout@v3 + - name: Get Node.js version + id: nodejs-version + run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: ${{ steps.nodejs-version.outputs.NODE_VERSION }} + registry-url: https://registry.npmjs.org/ + + - name: Prepare/restore cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }} + + - name: Install packages + run: npm ci + env: + NPM_TOKEN: ${{secrets.NPM_TOKEN_READ}} + + - name: Execute + run: | + npm start \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5fc1f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# compiled output +/dist +/node_modules + +# docker volumes +.data/* + +# tmp files +.tmp/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..85aee5a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..18d8b9d --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# VFS Global checker for visa dates availability + +### How to use: +1. Install packages with command: +```shell +nvm exec npm i +``` + +2. Update `.env` file + +3. Execute the command: +```shell +nvm exec npm start +``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3345aaf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,338 @@ +{ + "name": "vfs-global", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "vfs-global", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^1.6.0", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "tsconfig-paths": "^4.2.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/node": { + "version": "20.8.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", + "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "peer": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..daa3bdc --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "vfs-global", + "version": "1.0.0", + "description": "### TODO: Describe on how to use...", + "main": "index.js", + "scripts": { + "start": "ts-node -r tsconfig-paths/register src/index.ts" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^1.6.0", + "dotenv": "^16.3.1", + "ts-node": "^10.9.1", + "tsconfig-paths": "^4.2.0" + } +} diff --git a/src/checker.ts b/src/checker.ts new file mode 100644 index 0000000..f19821f --- /dev/null +++ b/src/checker.ts @@ -0,0 +1,102 @@ +import {Notifier} from "./notifier"; +import axios from 'axios'; +import {VfsResponseType} from "./vfs-response.type"; + +import dotenv from 'dotenv'; + +dotenv.config(); + +const authToken = process.env.AUTHENTICATED_TOKEN; +const checkUrl = process.env.VFS_GLOBAL_URL; + +export class Checker { + private notifier: Notifier = new Notifier(); + + public async execute() { + try { + const authToken = await this.authenticate() + await this.checkDates(authToken); + } catch (e: any) { + await this.notifier.sendMessage(`Something went wrong. Details: ${e.message}`); + } + } + + /* + * The auth process is manual for now. + * Later should be replaced with crawler + captcha solver: https://www.npmjs.com/package/2captcha + */ + private async authenticate(): Promise { + if (!authToken) { + throw new Error('Auth token is EMPTY!'); + } + + console.log("About to authenticate"); + let data; + try { + const response = await axios.post("https://lift-api.vfsglobal.com/user/login", "username=scorpionsve88@gmail.com&password=hyuJk1+hEKNMu7Av6l//7UjY/NcrL3FhayjXpXdNAD5RbhlqFiEjHsTbIRhTxusha6iiAdScjw7/w3Vler7i8TiUCGI6eVvhKNZYRPpH0XGWgvzhMqCWrHDTOmQAUOrUnE+miIM+WYjzgxdYmR53wjuH3/ZAmSiLDuCJIBgpuPw=&missioncode=pol&countrycode=blr&captcha_version=v2&captcha_api_key=03AFcWeA40seRw2M-vKFzR1fAyiTRCFQ7DQM6IbDAu3G3u9a9LvedsldpJnkuRMCppAMV6vtLDixxbD4wqF3ycIljSXGbB23bapCHVlb3qKLWD371TbfcAmVVqFSJpcCb0C-vSruT7gF-Zd4pdcu1usrsyhWU5QdOaSHPehW4z0XFbKcoXZcKcRYw16jnHo-kJ8zTuYU7Y_Qmf7zthk4wVpvD2spuGgugN6RemKzieYbvri8eM914-Sld1qV_q4e1UgmwKH65gaZW3BQuB4CO5M0K0se9XnTwGwaBLKNyaBDQEQZkFebHL9DitNGnqULZyQad2-8-FXw4FgIx01YLuq1nvMl46HpSLEZgtzV5anCjFstOqs4C0cNkWKmNlWYSCn4Nq8yVLYY8pP-DwBhpsnpVc-xfyOraejOpsQgDPoEqWfCLws6WgeMZyYIx38zOqDk76oPQeJdS6HHJIcmrq4c-Q_HeIIyFLi0B2m8M2ptuj9wrmMp7PGWHO7D5DOdtH5aXN1wf4w9O-hhge48LYYM2yqm_PX1XLi6utse3SRoU1xR24zny3QAtNUfTTookcPqjMKr5y048_OLubiJcP-IaSER1g-npoxOV-I8xgcCJR4ItHQZy4X3g", { + headers: { + ':authority': 'lift-api.vfsglobal.com', + ':method': 'POST', + ':path': '/user/login', + ':scheme': 'https', + Origin: 'https://visa.vfsglobal.com', + Referer: 'https://visa.vfsglobal.com/', + Route: `blr/ru/pol`, + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site', + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', + } + }); + data = response.data; + } catch (e) { + console.log('error: ', e); + } + + console.log('auth data: ', data); + + return Promise.resolve(authToken); + } + + private async checkDates(authToken: string) { + if (!checkUrl) { + throw new Error('URL is EMPTY!'); + } + + let data; + try { + const response = await axios.post(checkUrl, { + "countryCode": "blr", + "missionCode": "pol", + "vacCode": "POL-MIN", + "visaCategoryCode": "SENGEN", + "roleName": "Individual", + "loginUser": "scorpionsve88@gmail.com", + "payCode": "" + }, { + headers: { + Authorize: authToken, + Route: `blr/ru/pol`, + 'Sec-Ch-Ua': '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', + 'Sec-Ch-Ua-Mobile': '?0', + 'Sec-Ch-Ua-Platform': '"macOS"', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Site': 'same-site', + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', + } + }); + data = response.data; + } catch (e: any) { + console.log(e); + throw new Error('error'); + } + + if (data?.error?.description) { + throw new Error(`Error during fetching the available slots: ${data.error?.description}`); + } + + + await this.notifier.sendMessage(`Some dates are available: ${JSON.stringify(data.earliestSlotLists)}`); + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..c32f100 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +import {Checker} from './checker' +import dotenv from 'dotenv'; +dotenv.config(); + +(async () => { + const checker = new Checker(); + + await checker.execute(); +})() \ No newline at end of file diff --git a/src/notifier.ts b/src/notifier.ts new file mode 100644 index 0000000..ba934ae --- /dev/null +++ b/src/notifier.ts @@ -0,0 +1,7 @@ +export class Notifier { + public sendMessage(message: string): Promise { + console.log(`Notifying: ${message}`); + + return Promise.resolve(); + } +} \ No newline at end of file diff --git a/src/vfs-response.type.ts b/src/vfs-response.type.ts new file mode 100644 index 0000000..074d55c --- /dev/null +++ b/src/vfs-response.type.ts @@ -0,0 +1,7 @@ +export type VfsResponseType = { + "earliestSlotLists": any[], // should be changed + "error": { + "code": number, + "description": string + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..abba929 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "declaration": true, + "declarationMap": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "moduleResolution": "Node", + "target": "esNext", + "strict": true, + "sourceMap": true, + "outDir": "./dist", + "baseUrl": ".", + "incremental": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "skipLibCheck": true, + }, + "exclude": ["node_modules", "dist"], + "include": ["./src", "./test", "./types", "./scenarios"], + "incremental": true, + "typeRoots": [ + "./node_modules/@types" + ] +} \ No newline at end of file