Compare commits

...

435 Commits

Author SHA1 Message Date
github-actions[bot] b7930b25fd chore: release 3.4.0 (#1719) 2021-01-17 16:08:03 -05:00
Jef LeCompte 05720e519b ci: update verbiage for steps (#1721) 2021-01-17 16:07:06 -05:00
Jef LeCompte 8ece4b6412 ci: update names and steps (#1720) 2021-01-17 15:59:32 -05:00
Jef LeCompte 7997d6d22a ci: fix release-please 2021-01-17 15:35:03 -05:00
github-actions[bot] f474cc6966 chore: release 3.4.0 (#1391) 2021-01-17 15:27:32 -05:00
Jef LeCompte f87053cb02 refactor: use gts instead of xo
feat: add browser opening to test:notification
feat: add c8 and mocha for testing
feat: update Docker and ci
style: update editorconfig
2021-01-17 15:21:53 -05:00
Jef LeCompte dbde7814af chore: clean up and bump node version 2021-01-17 13:44:05 -05:00
wofnull b2ebac36c0 feat(caseking): add 3060ti/3070 cards / add missing 3080/3090 cards (#1715)
* Caseking add Asus 3060ti Models:
https://www.caseking.de/asus-geforce-rtx-3060-ti-rog-strix-o8g-8192-mb-gddr6-gcas-407.html
https://www.caseking.de/asus-geforce-rtx-3060-ti-dual-o8g-8192-mb-gddr6-gcas-410.html
https://www.caseking.de/asus-geforce-rtx-3060-ti-tuf-o8g-8192-mb-gddr6-gcas-412.html
https://www.caseking.de/asus-geforce-rtx-3060-ti-dual-8g-8192-mb-gddr6-gcas-411.html
https://www.caseking.de/asus-geforce-rtx-3060-ti-tuf-8g-8192-mb-gddr6-gcas-408.html
https://www.caseking.de/asus-geforce-rtx-3060-ti-rog-strix-8g-8192-mb-gddr6-gcas-409.html

* Caseking add EVGA 3060ti Moddels
https://www.caseking.de/evga-geforce-rtx-3060-ti-xc-gaming-8192-mb-gddr6-gcev-431.html
https://www.caseking.de/evga-geforce-rtx-3060-ti-ftw3-ultra-gaming-8192-mb-gddr6-gcev-403.html
https://www.caseking.de/evga-geforce-rtx-3060-ti-ftw3-black-gaming-8192-mb-gddr6-gcev-430.html
https://www.caseking.de/evga-geforce-rtx-3060-ti-xc-black-gaming-8192-mb-gddr6-gcev-432.html
https://www.caseking.de/evga-geforce-rtx-3060-ti-ftw3-gaming-8192-mb-gddr6-gcev-429.html

* Caseking add Gigabyte 3060ti Models:
https://www.caseking.de/gigabyte-geforce-rtx-3060-ti-eagle-oc-8g-8192-mb-gddr6-gcgb-349.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3060-ti-master-8g-8192-mb-gddr6-gcgb-346.html
https://www.caseking.de/gigabyte-geforce-rtx-3060-ti-gaming-oc-pro-8g-8192-mb-gddr6-gcgb-347.html
https://www.caseking.de/gigabyte-geforce-rtx-3060-ti-gaming-oc-8g-8192-mb-gddr6-gcgb-348.html
https://www.caseking.de/gigabyte-geforce-rtx-3060-ti-eagle-8g-8192-mb-gddr6-gcgb-350.html

* Caseking add Inno3d 3060ti Models:
https://www.caseking.de/inno3d-geforce-rtx-3060-ti-twin-x2-oc-8192-mb-gddr6-gci3-180.html
https://www.caseking.de/inno3d-geforce-rtx-3060-ti-ichill-x3-8192-mb-gddr6-gci3-179.html
https://www.caseking.de/inno3d-geforce-rtx-3060-ti-twin-x2-8192-mb-gddr6-gci3-181.html

* Caseking add MSI 3060ti Models
https://www.caseking.de/msi-geforce-rtx-3060-ti-gaming-x-trio-8192-mb-gddr6-gcmc-255.html
https://www.caseking.de/msi-geforce-rtx-3060-ti-ventus-2x-oc-8192-mb-gddr6-gcmc-246.html
https://www.caseking.de/msi-geforce-rtx-3060-ti-ventus-3x-oc-8192-mb-gddr6-gcmc-245.html

* Caseking add PNY 3060ti Models
https://www.caseking.de/pny-geforce-rtx-3060-ti-xlr8-gaming-revel-epic-x-8192-mb-gddr6-gcpn-080.html
https://www.caseking.de/pny-geforce-rtx-3060-ti-uprising-8g-8192-mb-gddr6-gcpn-079.html

* Caseking add Zotac 3060ti Models:
https://www.caseking.de/zotac-gaming-geforce-rtx-3060-ti-twin-edge-8192-mb-gddr6-gczt-169.html
https://www.caseking.de/zotac-gaming-geforce-rtx-3060-ti-twin-edge-oc-8192-mb-gddr6-gczt-170.html

* Caseking add Asus 3070 Models:
https://www.caseking.de/asus-geforce-rtx-3070-dual-8g-8192-mb-gddr6-gcas-404.html
https://www.caseking.de/asus-geforce-rtx-3070-tuf-o8g-8192-mb-gddr6-gcas-406.html
https://www.caseking.de/asus-geforce-rtx-3070-rog-strix-o8g-8192-mb-gddr6-gcas-403.html
https://www.caseking.de/asus-geforce-rtx-3070-dual-o8g-8192-mb-gddr6-gcas-405.html
https://www.caseking.de/asus-geforce-rtx-3070-rog-strix-8g-8192-mb-gddr6-gcas-415.html

* Caseking add EVGA 3070 Models

* Caseking add Gigabyte 3070 Models:
https://www.caseking.de/gigabyte-geforce-rtx-3070-gaming-oc-8g-8192-mb-gddr6-gcgb-338.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3070-master-8g-8192-mb-gddr6-gcgb-343.html
https://www.caseking.de/gigabyte-geforce-rtx-3070-vision-oc-8g-8192-mb-gddr6-gcgb-344.html
https://www.caseking.de/gigabyte-geforce-rtx-3070-eagle-8g-8192-mb-gddr6-gcgb-340.html
https://www.caseking.de/gigabyte-geforce-rtx-3070-eagle-oc-8g-8192-mb-gddr6-gcgb-339.html

List from EVGA Previuous commit:
https://www.caseking.de/evga-geforce-rtx-3070-xc3-black-gaming-8192-mb-gddr6-gcev-424.html
https://www.caseking.de/evga-geforce-rtx-3070-xc3-ultra-gaming-8192-mb-gddr6-gcev-426.html
https://www.caseking.de/evga-geforce-rtx-3070-ftw3-ultra-8192-mb-gddr6-gcev-428.html
https://www.caseking.de/evga-geforce-rtx-3070-xc3-8192-mb-gddr6-gcev-425.html
https://www.caseking.de/evga-geforce-rtx-3070-ftw3-8192-mb-gddr6-gcev-427.html

* Caseking add Inno3D 3070 Models:
https://www.caseking.de/inno3d-geforce-rtx-3070-twin-x2-8192-mb-gddr6-gci3-176.html
https://www.caseking.de/inno3d-geforce-rtx-3070-ichill-x3-8192-mb-gddr6-gci3-174.html
https://www.caseking.de/inno3d-geforce-rtx-3070-ichill-x4-8192-mb-gddr6-gci3-173.html
https://www.caseking.de/inno3d-geforce-rtx-3070-twin-x2-oc-8192-mb-gddr6-gci3-175.html

* Caseking add MSI 3070 Models:
https://www.caseking.de/msi-geforce-rtx-3070-gaming-x-trio-8192-mb-gddr6-gcmc-250.html
https://www.caseking.de/msi-geforce-rtx-3070-suprim-8g-8192-mb-gddr6-gcmc-256.html
https://www.caseking.de/msi-geforce-rtx-3070-ventus-2x-oc-8192-mb-gddr6-gcmc-249.html
https://www.caseking.de/msi-geforce-rtx-3070-ventus-3x-oc-8192-mb-gddr6-gcmc-251.html
https://www.caseking.de/msi-geforce-rtx-3070-suprim-x-8g-8192-mb-gddr6-gcmc-254.html

* Caseking add PNY 3070 Models:
https://www.caseking.de/pny-geforce-rtx-3070-xlr8-gaming-revel-epic-x-rgb-8192-mb-gddr6-gcpn-078.html
https://www.caseking.de/pny-geforce-rtx-3070-dual-fan-8192-mb-gddr6-gcpn-077.html

* Caseking add Zotac 3070 Models:
https://www.caseking.de/zotac-gaming-geforce-rtx-3070-twin-edge-8192-mb-gddr6-gczt-164.html
https://www.caseking.de/zotac-gaming-geforce-rtx-3070-twin-edge-oc-8192-mb-gddr6-gczt-168.html
https://www.caseking.de/zotac-gaming-geforce-rtx-3070-twin-edge-oc-white-8192-mb-gddr6-gczt-171.html

* Caseking added missing 3080 Models from Store:
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3080-xtreme-10g-10240-mb-gddr6x-gcgb-333.html
https://www.caseking.de/msi-geforce-rtx-3080-suprim-x-10g-10240-mb-gddr6x-gcmc-253.html
https://www.caseking.de/asus-geforce-rtx-3080-ekwb-10g-10240-mb-gddr6x-gcas-413.html
https://www.caseking.de/inno3d-geforce-rtx-3080-ichill-frostbite-10240-mb-gddr6x-gci3-177.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3080-xtreme-waterforce-wb-10g-10240-mb-gddr6x-gcgb-352.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3080-xtreme-waterforce-10g-10240-mb-gddr6x-gcgb-351.html
https://www.caseking.de/evga-geforce-rtx-3080-xc3-ultra-hybrid-gaming-10240-mb-gddr6x-gcev-435.html
https://www.caseking.de/evga-geforce-rtx-3080-ftw3-ultra-hybrid-gaming-10240-mb-gddr6x-gcev-436.html
https://www.caseking.de/gigabyte-geforce-rtx-3080-eagle-10g-10240-mb-gddr6x-gcgb-353.html

* Caseking added missing 3090 Models from Store:
https://www.caseking.de/asus-geforce-rtx-3090-ekwb-24g-24576-mb-gddr6x-gcas-414.html
https://www.caseking.de/msi-geforce-rtx-3090-ventus-3x-24g-oc-24576-mb-gddr6x-gcmc-243.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3090-xtreme-waterforce-wb-24g-24576-mb-gddr6x-gcgb-355.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3090-xtreme-waterforce-24g-24576-mb-gddr6x-gcgb-354.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3090-xtreme-24g-24576-mb-gddr6x-gcgb-335.html
https://www.caseking.de/evga-geforce-rtx-3090-ftw3-ultra-hybrid-gaming-24576-mb-gddr6x-gcev-434.html
https://www.caseking.de/evga-geforce-rtx-3090-xc3-ultra-hybrid-gaming-24576-mb-gddr6x-gcev-433.html
https://www.caseking.de/gigabyte-aorus-geforce-rtx-3090-master-24g-24576-mb-gddr6x-gcgb-334.html
https://www.caseking.de/inno3d-geforce-rtx-3090-ichill-frostbite-24576-mb-gddr6x-gci3-178.html
https://www.caseking.de/msi-geforce-rtx-3090-suprim-x-24g-24576-mb-gddr6x-gcmc-252.html
https://www.caseking.de/gigabyte-geforce-rtx-3090-vision-oc-24g-24576-mb-gddr6x-gcgb-341.html
https://www.caseking.de/gigabyte-geforce-rtx-3090-turbo-24g-24576-mb-gddr6x-gcgb-330.html
https://www.caseking.de/gigabyte-geforce-rtx-3090-eagle-24g-24576-mb-gddr6x-gcgb-342.html

Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2021-01-17 13:42:01 -05:00
pbaum83 b03d24217f feat: add command parameter to set custom dotenv conf (#1590) 2021-01-17 12:47:33 -05:00
wofnull 2fa893795f feat(store): addition of several australian sites (#1651)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2021-01-17 12:45:13 -05:00
dependabot[bot] 122e68a764 chore(deps-dev): bump @types/node from 14.14.20 to 14.14.21 (#1695)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.20 to 14.14.21.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 12:36:41 -05:00
Martazza cb898c7923 feat(store): add more italian sites (#1701) 2021-01-17 12:36:28 -05:00
neatchee 09827741ae feat(store): specify links to navigate to between product searches (#1542)
Fixes #1504

When querying a store, if `deterrentLinks` has been defined, pick one at random and navigate there then wait 3 seconds. This should help reduce the likelihood of being sent to a captcha on subsequent page loads from the same store.
2021-01-17 08:27:08 -05:00
wofnull 2120d2901d fix(galaxus): update selector (#1705) 2021-01-17 08:22:31 -05:00
wofnull 3f191bbd00 fix(newegg): false positives (all stores) (#1714) 2021-01-17 08:22:10 -05:00
dependabot[bot] 724f6b19a1 chore(deps-dev): bump @types/node-fetch from 2.5.7 to 2.5.8 (#1696)
Bumps [@types/node-fetch](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node-fetch) from 2.5.7 to 2.5.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node-fetch)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-15 15:30:01 -05:00
wofnull bc45fd8d11 chore(galaxus): update selector (#1693) 2021-01-15 13:27:07 -05:00
wofnull 0a1198b69c fix(acompc): false positives (#1699)
Update selector has changed
2021-01-15 13:26:35 -05:00
wofnull e0849c4dc2 fix(computeruniverse): false positives (#1698)
Add additional out of stock message
2021-01-15 13:26:14 -05:00
dependabot[bot] 75b2460aea chore(deps-dev): bump webpack from 5.13.0 to 5.14.0 (#1692)
Bumps [webpack](https://github.com/webpack/webpack) from 5.13.0 to 5.14.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.13.0...v5.14.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:30:11 -05:00
dependabot[bot] 50ee40a2d4 chore(deps): bump puppeteer-extra from 3.1.15 to 3.1.16 (#1678)
Bumps [puppeteer-extra](https://github.com/berstend/puppeteer-extra) from 3.1.15 to 3.1.16.
- [Release notes](https://github.com/berstend/puppeteer-extra/releases)
- [Commits](https://github.com/berstend/puppeteer-extra/compare/puppeteer-extra@3.1.15...puppeteer-extra@3.1.16)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:25:55 -05:00
dependabot[bot] 9d7f908e04 chore(deps): bump puppeteer-extra-plugin-block-resources from 2.2.7 to 2.2.8 (#1691)
Bumps [puppeteer-extra-plugin-block-resources](https://github.com/berstend/puppeteer-extra) from 2.2.7 to 2.2.8.
- [Release notes](https://github.com/berstend/puppeteer-extra/releases)
- [Commits](https://github.com/berstend/puppeteer-extra/compare/puppeteer-extra-plugin-block-resources@2.2.7...puppeteer-extra-plugin-block-resources@2.2.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:25:45 -05:00
dependabot[bot] 3b14ec7574 chore(deps): bump google-github-actions/release-please-action from v2.14 to v2.15 (#1655)
Bumps [google-github-actions/release-please-action](https://github.com/google-github-actions/release-please-action) from v2.14 to v2.15.
- [Release notes](https://github.com/google-github-actions/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/release-please-action/compare/v2.14...88a82e1f9574f0a8bcacf1a13f84ef3d2c6659f3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2021-01-14 13:19:02 -05:00
dependabot[bot] 57b3a500ae chore(deps): bump @slack/web-api from 5.15.0 to 6.0.0 (#1669)
Bumps [@slack/web-api](https://github.com/slackapi/node-slack-sdk) from 5.15.0 to 6.0.0.
- [Release notes](https://github.com/slackapi/node-slack-sdk/releases)
- [Commits](https://github.com/slackapi/node-slack-sdk/compare/@slack/web-api@5.15.0...@slack/web-api@6.0.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:18:42 -05:00
wofnull b821eab273 fix(bandh): asus cards / out of stock check added (#1670) 2021-01-14 13:18:29 -05:00
dependabot[bot] 513f578fdc chore(deps): bump puppeteer-extra-plugin-stealth from 2.6.5 to 2.6.6 (#1680)
Bumps [puppeteer-extra-plugin-stealth](https://github.com/berstend/puppeteer-extra) from 2.6.5 to 2.6.6.
- [Release notes](https://github.com/berstend/puppeteer-extra/releases)
- [Commits](https://github.com/berstend/puppeteer-extra/compare/puppeteer-extra-plugin-stealth@2.6.5...puppeteer-extra-plugin-stealth@2.6.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:17:34 -05:00
dependabot[bot] a6a69e7ae5 chore(deps): bump twilio from 3.54.2 to 3.55.0 (#1679)
Bumps [twilio](https://github.com/twilio/twilio-node) from 3.54.2 to 3.55.0.
- [Release notes](https://github.com/twilio/twilio-node/releases)
- [Changelog](https://github.com/twilio/twilio-node/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-node/compare/3.54.2...3.55.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:17:21 -05:00
dependabot[bot] 58761fc48e chore(deps): bump puppeteer-extra-plugin-adblocker from 2.11.9 to 2.11.10 (#1681)
Bumps [puppeteer-extra-plugin-adblocker](https://github.com/berstend/puppeteer-extra) from 2.11.9 to 2.11.10.
- [Release notes](https://github.com/berstend/puppeteer-extra/releases)
- [Commits](https://github.com/berstend/puppeteer-extra/compare/puppeteer-extra-plugin-adblocker@2.11.9...puppeteer-extra-plugin-adblocker@2.11.10)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-14 13:17:08 -05:00
wofnull 3ab0de6e86 chore(computeruniverse): add 3060ti cards (#1665) 2021-01-14 08:39:09 -05:00
wofnull be541713a8 fix(wipoid): added 3090/3080/3070/3060ti/ryzen store items (#1683) 2021-01-14 08:22:21 -05:00
wofnull 84382def6f feat(vsgamers): add maxPrice selector(#1682) 2021-01-14 08:14:44 -05:00
wofnull a768eb4cf5 fix(galaxus): update selector ( 14.01.2020 07:00 ) (#1664) 2021-01-14 08:13:54 -05:00
Jef LeCompte ca2580d72b docs: add hyperlinks 2021-01-12 17:36:46 -05:00
Jef LeCompte 9c35e728ac docs(twitch): add instructions on how to get tokens 2021-01-12 17:30:51 -05:00
Jef LeCompte 52c7e74372 chore(lint): add void for dangling promise 2021-01-12 12:18:50 -05:00
Jef LeCompte c479ce2b6a chore(deps): bump dependencies 2021-01-12 10:36:54 -05:00
xal3xhx 83508bc5ea feat(twilio): add support to have multiple numbers (#1450)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2021-01-11 13:48:03 -05:00
wofnull c9cda1e4e5 feat(galaxus): update selector, add out of stock check (#1607) 2021-01-11 12:16:04 -05:00
Jef LeCompte d0a4667a64 feat(asus): add outOfStock label (#1653)
Resolves #368
2021-01-11 12:14:15 -05:00
dependabot[bot] 459e9af34c chore(deps-dev): bump webpack from 5.11.1 to 5.12.3 (#1650)
Bumps [webpack](https://github.com/webpack/webpack) from 5.11.1 to 5.12.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.11.1...v5.12.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-11 12:01:34 -05:00
dependabot[bot] 8ed5daf729 chore(deps): bump amannn/action-semantic-pull-request from v2.2.0 to v3.1.0 (#1652)
Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from v2.2.0 to v3.1.0.
- [Release notes](https://github.com/amannn/action-semantic-pull-request/releases)
- [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v2.2.0...d2ab30dcffc66150340abb5b947d518a3c3ce9cb)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-11 12:01:22 -05:00
dependabot[bot] f8af5a85c0 chore(deps): bump messaging-api-telegram from 1.0.1 to 1.0.4 (#1649)
Bumps [messaging-api-telegram](https://github.com/Yoctol/messaging-apis) from 1.0.1 to 1.0.4.
- [Release notes](https://github.com/Yoctol/messaging-apis/releases)
- [Changelog](https://github.com/Yoctol/messaging-apis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Yoctol/messaging-apis/compare/v1.0.1...v1.0.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-11 11:56:44 -05:00
Matt Conte 20bea85e41 fix(store): Update 30 series links and models for store.asus.com (#1645)
Fixes #1637
2021-01-10 13:03:01 -05:00
tilda 943ab837e2 docs: fix spelling in "Creating a Discord webhook" (#1646) 2021-01-10 13:02:14 -05:00
Benjamin Knofe 9c2ea8dbe9 feat(proshop-de): add proshop-de inStock selector (#1633) 2021-01-08 15:34:10 -05:00
dependabot[bot] 30f3fab419 chore(deps): bump open from 7.3.0 to 7.3.1 (#1630)
Bumps [open](https://github.com/sindresorhus/open) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/sindresorhus/open/releases)
- [Commits](https://github.com/sindresorhus/open/compare/v7.3.0...v7.3.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-08 10:27:57 -05:00
Jordan Tucker c0638d2e4b feat(web): properly set for attribute for labels (#1626) 2021-01-08 10:23:16 -05:00
dependabot[bot] 426a8ce015 chore(deps): bump google-github-actions/release-please-action from v2.13 to v2.14 (#1629)
Bumps [google-github-actions/release-please-action](https://github.com/google-github-actions/release-please-action) from v2.13 to v2.14.
- [Release notes](https://github.com/google-github-actions/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/release-please-action/compare/v2.13...7e0f05fbdf9f233ed4d15b06069125e83ae0c7e0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-08 10:05:49 -05:00
dependabot[bot] 21d0a94a8e chore(deps): bump @slack/web-api from 5.14.0 to 5.15.0 (#1606)
Bumps [@slack/web-api](https://github.com/slackapi/node-slack-sdk) from 5.14.0 to 5.15.0.
- [Release notes](https://github.com/slackapi/node-slack-sdk/releases)
- [Commits](https://github.com/slackapi/node-slack-sdk/compare/@slack/web-api@5.14.0...@slack/web-api@5.15.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-07 11:14:17 -05:00
wofnull 8faf3202e7 fix(bestbuy): shorter pageview urls and missing carturl links (#1613)
Fixes #1610
2021-01-07 10:53:08 -05:00
wofnull ef926d2282 feat(store): add SG Location for Amazon and Newegg (#1600) 2021-01-07 10:51:20 -05:00
dependabot[bot] 3f62921439 chore(deps-dev): bump nodemon from 2.0.6 to 2.0.7 (#1621)
Bumps [nodemon](https://github.com/remy/nodemon) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.6...v2.0.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-07 10:42:40 -05:00
dependabot[bot] 1ed8eca6f9 chore(deps): bump twilio from 3.54.1 to 3.54.2 (#1622)
Bumps [twilio](https://github.com/twilio/twilio-node) from 3.54.1 to 3.54.2.
- [Release notes](https://github.com/twilio/twilio-node/releases)
- [Changelog](https://github.com/twilio/twilio-node/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-node/compare/3.54.1...3.54.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-07 10:42:24 -05:00
Jef LeCompte 53cb59aada chore: update bug template 2021-01-06 17:22:52 -05:00
dependabot[bot] 8d0a32ca22 chore(deps-dev): bump @types/node from 14.14.19 to 14.14.20 (#1597)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.19 to 14.14.20.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-05 14:07:04 -05:00
wofnull 445a00728f fix(galaxus): update selector (#1599) 2021-01-05 08:18:58 -05:00
dependabot[bot] 6a4049bbc3 chore(deps-dev): bump webpack from 5.11.0 to 5.11.1 (#1541)
Bumps [webpack](https://github.com/webpack/webpack) from 5.11.0 to 5.11.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.11.0...v5.11.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-04 18:13:33 -05:00
dependabot[bot] 13d4ee6a71 chore(deps): bump twitch from 4.3.6 to 4.3.8 (#1533)
Bumps [twitch](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch) from 4.3.6 to 4.3.8.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.8/packages/twitch)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-04 18:13:23 -05:00
dependabot[bot] a74980b728 chore(deps): bump twitch-chat-client from 4.3.6 to 4.3.8 (#1534)
Bumps [twitch-chat-client](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch-chat-client) from 4.3.6 to 4.3.8.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.8/packages/twitch-chat-client)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-03 02:17:20 -05:00
dependabot[bot] 8a1874216a chore(deps-dev): bump @types/node from 14.14.16 to 14.14.19 (#1585)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.16 to 14.14.19.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-03 02:16:42 -05:00
dependabot[bot] 0ef76d66bc chore(deps): bump google-github-actions/release-please-action from v2.12.3 to v2.13 (#1558)
Bumps [google-github-actions/release-please-action](https://github.com/google-github-actions/release-please-action) from v2.12.3 to v2.13.
- [Release notes](https://github.com/google-github-actions/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/release-please-action/compare/v2.12.3...f8ac173f7087940f7d90793fd96e1f83d43ee772)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-03 02:16:22 -05:00
Anthony Tam 082776cfca fix(store): update missing/mislabeled cards for Canadian retailers (#1574) 2021-01-03 02:13:18 -05:00
wofnull ad5bd55c1a fix(galaxus): update selector (#1578) 2021-01-03 02:11:48 -05:00
X123Moin 4f86d2462e fix(store): update out of stock detection for MediaMarkt and Saturn (#1549)
Fixes #1545
2021-01-03 02:09:14 -05:00
Anthony Tam 8ab6e1f1d8 feat(store): add GPU and CPU support for Vuugo (#1555) 2021-01-03 02:06:51 -05:00
CyberMew f9a3d03f35 feat(pushover): add screenshot to push notification if available (#1552) 2021-01-03 02:05:36 -05:00
Reid Kornman 9ef83fd1d2 chore(bestbuy): add 3060ti cards (#1548) 2021-01-03 02:04:53 -05:00
Staffan 8e5c28e10b chore(proshop-dk): add 3060ti, add 3070, update 3080, update 3090, add ryzen cpus (#1526) 2021-01-03 02:03:11 -05:00
dependabot[bot] de69f7ae8a chore(deps): bump twitch-auth from 4.3.6 to 4.3.8 (#1532)
Bumps [twitch-auth](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch-auth) from 4.3.6 to 4.3.8.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.8/packages/twitch-auth)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-03 02:02:05 -05:00
Collin Garvey ca1564e8fa chore(philips-hue): correct the log text (#1523) 2020-12-27 02:18:06 -05:00
Jef LeCompte a908ce417b chore(redis): init client once
Regression of 6bc7737ef0
2020-12-26 07:37:33 -08:00
Jef LeCompte 6bc7737ef0 fix: disable redis if not configured
Fixes #1516
2020-12-26 07:28:49 -08:00
Dan Robinson 14998d87f9 chore(evga): add 3060ti cards 2020-12-25 19:24:04 -05:00
dependabot[bot] 76761c5b8d chore(deps): bump amannn/action-semantic-pull-request (#1494)
Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from v2.1.1 to v2.2.0.
- [Release notes](https://github.com/amannn/action-semantic-pull-request/releases)
- [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v2.1.1...e92d269774194a4d390ad91a817b19ccb588410e)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-25 19:22:47 -05:00
dependabot[bot] a402c64f5e chore(deps): bump cheerio from 1.0.0-rc.3 to 1.0.0-rc.5 (#1495)
Bumps [cheerio](https://github.com/cheeriojs/cheerio) from 1.0.0-rc.3 to 1.0.0-rc.5.
- [Release notes](https://github.com/cheeriojs/cheerio/releases)
- [Changelog](https://github.com/cheeriojs/cheerio/blob/main/History.md)
- [Commits](https://github.com/cheeriojs/cheerio/compare/1.0.0-rc.3...v1.0.0-rc.5)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-25 19:22:35 -05:00
dependabot[bot] e893d79ad7 chore(deps-dev): bump @types/node from 14.14.14 to 14.14.16 (#1506)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.16.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-25 19:14:49 -05:00
Bailey Miller fb82526a42 feat: add redis (#1390) 2020-12-25 19:14:21 -05:00
neatchee 90fb430b71 fix(amazon-de-warehouse): update wrong maxPrice selector (#1514) 2020-12-25 19:10:19 -05:00
Sergej Lopatkin 5b70ff14cb feat(store): add equippr & futurex for DE region (#1501) 2020-12-25 19:03:36 -05:00
erwinc1 0c6e2d587d fix: properly pass array entries as separate indices (#1502) 2020-12-25 19:01:23 -05:00
neatchee 1cf618c1c1 feat(lookup): add protection against infinite recursion for Cloudflare (#1505)
Fixes #1459
Fixes #1490
2020-12-23 22:23:43 -08:00
StanZha 28d1cf90b8 chore(store): rx6800xt for memoryexpress, amazon-ca (#1491)
* rx6900xt urls added for amd official store, newegg and bestbuy

* added rx6900xt microcenter url

* linter issue fix

* few more 6800xt added for Canada
2020-12-22 11:57:57 -05:00
Jef LeCompte f34a808451 feat(lookup): add max price for xbox
Resolves #1436
2020-12-21 16:09:37 -05:00
sohaiiil eb59dc3433 fix(store): link builder in UK stores (#1486)
Going to use static links instead now.
2020-12-21 13:01:53 -05:00
KnotenJoe beee355563 feat(store): add pcking and acompc (#1470)
* Create pcking

Another store for Germany.  I tested the code on my pc.

* docs: add pcking to store list

* Rename pcking to pcking.ts

* Update index.ts

* Update filter.md

* Update index.ts

* Create acompc.ts

* chore: linting

* chore: linting

Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-21 12:58:46 -05:00
David Gauch 5a6b252ae1 chore(newegg): add links for rx6800xt and rx6800 (#1484)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-21 17:40:39 +00:00
Jef LeCompte 0c80d6caea docs: add missing font key 2020-12-21 12:37:39 -05:00
Jef LeCompte 272b49b4ac docs: change fonts to Roboto 2020-12-21 12:33:33 -05:00
James Hinton ec8d3571cf feat(store): add johnlewis store, add shopto store (#1481)
* add `johnlewis` store

* feat: add `shopto` store

* chore: linting

* chore: linting

Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-20 18:00:00 -05:00
KnotenJoe 7a5bc22ba8 fix(galaxus): maxPrice selector (#1469) 2020-12-20 17:51:31 -05:00
sohaiiil 673b5f325c docs(reference): add AWD-IT (#1460) 2020-12-19 12:12:33 -05:00
Richard Chen Zheng 70b2e7c408 docs(reference): add AMD 6800, 6800xt, 6900xt (#1463) 2020-12-19 12:11:19 -05:00
Phillip Kramp 4debcd33a7 chore(amazon): add nvidia and amd cards (#1430) 2020-12-18 09:23:55 -05:00
dependabot[bot] 0b7d92341a chore(deps): bump google-github-actions/release-please-action from v2.12.2 to v2.12.3 (#1454)
Bumps [google-github-actions/release-please-action](https://github.com/google-github-actions/release-please-action) from v2.12.2 to v2.12.3.
- [Release notes](https://github.com/google-github-actions/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/release-please-action/compare/v2.12.2...ecf21cd22e32f8a23d66f762091b994d1a60c1c4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-18 09:23:11 -05:00
dependabot[bot] 0cc5de95ca chore(deps): bump dorny/paths-filter from v2.6.0 to v2.7.0 (#1453)
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from v2.6.0 to v2.7.0.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/v2.6.0...4e7fcc37b4770a7082a9be52b4c543d2839f55df)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-18 09:21:58 -05:00
dependabot[bot] bc788cbd95 chore(deps-dev): bump webpack from 5.10.3 to 5.11.0 (#1456)
Bumps [webpack](https://github.com/webpack/webpack) from 5.10.3 to 5.11.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.10.3...v5.11.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-18 09:11:45 -05:00
Mark Dietzer ab037029b6 fix(proxy): update proxy module (#1451)
Fixes #1437
2020-12-18 09:07:03 -05:00
Jef LeCompte 6e2a16238c feat: remove stale user agents, use top 50
This change should vastly improve success rate.
2020-12-17 19:39:23 -05:00
neatchee f86a8259f3 feat(lookup): handle Cloudflare DDoS protection (#1434)
Resolves #1297
2020-12-17 11:49:43 -05:00
dependabot[bot] 2b5588bd46 chore(deps): bump actions/setup-node from v2.1.3 to v2.1.4 (#1439)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from v2.1.3 to v2.1.4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v2.1.3...c46424eee26de4078d34105d3de3cc4992202b1e)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-17 11:45:41 -05:00
dependabot[bot] cdc3a84d2d chore(deps-dev): bump @types/node from 14.14.13 to 14.14.14 (#1431)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.13 to 14.14.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-17 11:45:35 -05:00
dependabot[bot] ef9afb8d69 chore(deps-dev): bump webpack from 5.10.1 to 5.10.3 (#1432)
Bumps [webpack](https://github.com/webpack/webpack) from 5.10.1 to 5.10.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.10.1...v5.10.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-17 11:45:28 -05:00
dependabot[bot] 8836a1c1c4 chore(deps): bump twilio from 3.54.0 to 3.54.1 (#1440)
Bumps [twilio](https://github.com/twilio/twilio-node) from 3.54.0 to 3.54.1.
- [Release notes](https://github.com/twilio/twilio-node/releases)
- [Changelog](https://github.com/twilio/twilio-node/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-node/compare/3.54.0...3.54.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-17 11:45:19 -05:00
Jef LeCompte 96ae818e84 fix(lookup): remove mobile versions of user agent
Removing mobile versions of user agents should help
us with false positives, as the mobile version may give
different selectors which we cannot parse correctly.
2020-12-17 11:34:27 -05:00
Eugene Shalygin 7425e6437f chore(store): add some radeon models for German stores (#1426) 2020-12-15 17:11:20 -05:00
Mark Dietzer f65df4ce56 fix(proxy): fix requests with proxies (#1408) 2020-12-15 17:08:38 -05:00
Jef LeCompte ecdb7a058d style(docs): change code font to JetBrains Mono 2020-12-15 10:23:52 -05:00
carrierfry 02d29c3c64 fix(lookup): check out of stock before price (#1422) 2020-12-15 09:27:05 -05:00
RitoFaith ca59777917 feat(azerty): add ryzen 5000 series (#878) 2020-12-15 08:10:26 -05:00
Jef LeCompte 8db16dd0cb docs: fix hotlink 2020-12-15 07:49:16 -05:00
Jef LeCompte a9b2ecfd48 docs: fix banner location 2020-12-15 00:37:08 -05:00
Jef LeCompte 8fdfa4d57c style(notification): update desktop look and feel 2020-12-15 00:35:20 -05:00
Jef LeCompte 64898b8ae3 chore(deps): bump twitch, notifier, mailer, typescript, node, and webpack 2020-12-15 00:28:04 -05:00
Jef LeCompte d592cd5d77 chore: update template, typos in docs (#1386) 2020-12-15 00:23:04 -05:00
StanZha 316b3bbb81 chore(store): add rx6900xt for newegg(-ca), amd-ca, bestbuy, and microcenter (#1420) 2020-12-15 00:22:47 -05:00
Mark Dietzer be1953b206 feat(proxy): fallback to a global proxy list (#1388) 2020-12-13 16:37:54 -05:00
Mark Dietzer 445689efc4 fix(webui): handling of file serving (#1383) 2020-12-13 10:40:04 -05:00
sohaiiil 2d25c464f8 docs(store): add missing uk store (#1384) 2020-12-13 10:38:27 -05:00
Jef LeCompte 704fa393c2 ci: update release-please 2020-12-13 00:48:25 -05:00
dependabot[bot] 769f19efa2 chore(deps): bump GoogleCloudPlatform/release-please-action from v2.10 to v2.12.2 (#1339)
Bumps [GoogleCloudPlatform/release-please-action](https://github.com/GoogleCloudPlatform/release-please-action) from v2.10 to v2.12.2.
- [Release notes](https://github.com/GoogleCloudPlatform/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleCloudPlatform/release-please-action/compare/v2.10...9a3489838773d66aa63a899ec5dbd26f43b4837b)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-13 00:44:31 -05:00
github-actions[bot] b97d581607 chore: release 3.3.0 (#1233) 2020-12-13 00:41:50 -05:00
Mark Dietzer eb700762a4 fix(adblock): proxy another function to produce less errors (#1379) 2020-12-13 00:40:57 -05:00
Jef LeCompte 38630d478a docs: update mkdocs appearance 2020-12-13 00:26:47 -05:00
Jef LeCompte 2a5e2e8733 chore: update logos 2020-12-13 00:23:20 -05:00
James White 579cb97a0d feat(store): add several Australian stores, add some 3080 brands/models (#1367) 2020-12-12 20:14:02 -05:00
Conor Broderick f70998f0d9 feat(store): add Irish store variants (#1373) 2020-12-12 20:08:05 -05:00
sohaiiil 02825d009b fix(store): update UK stores (#1372) 2020-12-12 20:07:10 -05:00
Jef LeCompte 0d75025cbb docs(discord): add xbox* groups
Resolves #1352
2020-12-12 09:46:43 -05:00
Mike H db47827e6e docs(filter): update El Corte Inglés location (#1369) 2020-12-12 09:44:03 -05:00
Jef LeCompte c3beedced8 fix(newegg): price selector and mobile inStock
Fixes #1356
2020-12-12 09:38:35 -05:00
Dylan Fontaine 0525119b9b fix(bestbuy-ca): update selectors to help false positives (#1278)
Resolves #895
2020-12-12 09:23:19 -05:00
Jef LeCompte b6964b02f3 fix(amazon-nl): inStock selector
Fixes #1366
2020-12-12 09:19:28 -05:00
moiLegacy 7329c6ede0 fix(newegg): dedupe nitro+ models (#1300)
Fixes #1230
2020-12-12 09:06:41 -05:00
sohaiiil cccfde245a feat(discord): dynamic currency symbol (#1328) 2020-12-12 09:01:54 -05:00
Jef LeCompte ad0b2fe525 fix(discord): notification groupings 2020-12-11 18:04:22 -05:00
Jef LeCompte 064ce83f03 ci: add workflow_dispatch for quick releases 2020-12-11 13:28:32 -05:00
Jef LeCompte ef452d8e58 fix(config): remove quotes 2020-12-11 13:27:19 -05:00
Jef LeCompte dca916b64e fix(config): disable docker by default 2020-12-11 12:50:18 -05:00
Jef LeCompte e2bf5749c1 docs: update docker-compose title 2020-12-11 12:38:29 -05:00
Jef LeCompte da78362045 docs: update docker-compose information 2020-12-11 12:37:33 -05:00
Egidijus Ligeika c74ea28014 fix(docker): run in docker, and build scripts for docker (#1291)
Updates unnecessary need to grant special privileges when running in Docker.
2020-12-11 12:13:11 -05:00
Will Whitney 67b19a7a8b feat(playstation): add queuing selector (#1173) 2020-12-11 12:08:47 -05:00
Jef LeCompte 5786481b31 docs: medimax is de store 2020-12-11 12:02:48 -05:00
Jef LeCompte 9b7c7e2881 fix: .env backwards compatibility 2020-12-11 08:11:57 -05:00
Jef LeCompte 7e3020a927 docs: include max prices for adding a store
Based on https://github.com/jef/streetmerchant/discussions/1146#discussioncomment-168047
2020-12-11 02:56:37 -05:00
Jef LeCompte 3386e8f50d revert: allow users to still use USER_AGENT
Removed from documentation, but older users can utilize
until fully removed in 4.0.0
2020-12-11 02:50:04 -05:00
dependabot[bot] 7bfcc81fdc chore(deps): bump twilio from 3.53.0 to 3.54.0 (#1287)
Bumps [twilio](https://github.com/twilio/twilio-node) from 3.53.0 to 3.54.0.
- [Release notes](https://github.com/twilio/twilio-node/releases)
- [Changelog](https://github.com/twilio/twilio-node/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-node/compare/3.53.0...3.54.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-11 02:41:05 -05:00
dependabot[bot] 37962f00e5 chore(deps): bump twitch-chat-client from 4.3.5 to 4.3.6 (#1308)
Bumps [twitch-chat-client](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch-chat-client) from 4.3.5 to 4.3.6.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.6/packages/twitch-chat-client)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-11 02:06:54 -05:00
dependabot[bot] d92d58d235 chore(deps-dev): bump @types/puppeteer from 5.4.1 to 5.4.2 (#1289)
Bumps [@types/puppeteer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/puppeteer) from 5.4.1 to 5.4.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/puppeteer)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-11 02:06:35 -05:00
Jef LeCompte 9b3906ca00 refactor: change .env to be dotenv (#1341) 2020-12-11 01:57:49 -05:00
dependabot[bot] 0683430768 chore(deps): bump actions/setup-node from v2.1.2 to v2.1.3 (#1338)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from v2.1.2 to v2.1.3.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v2.1.2...27082cecf3ff7a1742dbd5e12605f0cb59dce2d9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-11 01:16:34 -05:00
dependabot[bot] b6ea0ea991 chore(deps-dev): bump @types/node from 14.14.10 to 14.14.12 (#1340)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.10 to 14.14.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-11 01:16:23 -05:00
Jef LeCompte 68eede5487 docs: update format for models and countries 2020-12-11 01:14:39 -05:00
moodswung 29175c77a8 feat(store): add darkhero motherboard to asus and microcenter (#1336) 2020-12-11 01:13:26 -05:00
xeaon a44621f8f5 fix: add setRequestInterception (#1312)
Fixes #826
2020-12-11 01:09:08 -05:00
Dylan Fontaine 27cfb94de8 feat(store): add EBGames (#1281) 2020-12-11 01:02:32 -05:00
Jef LeCompte b599c23b51 feat(lookup): use random user agents (#1335) 2020-12-11 00:33:32 -05:00
Jef LeCompte 2115c0c906 chore: remove default label on bug issue 2020-12-10 15:14:21 -05:00
Eugene Shalygin 4f60ad2a82 chore(store): add a few AMD listings for German stores (#1321) 2020-12-10 13:28:30 -05:00
Warwick Marangos 8d192317ba feat(notification): add sound player executable option (#1301)
Pass the path to the player executable as a players array to play-sound so that it will check if the executable exists.
2020-12-09 20:59:10 -05:00
SizzlinSeal 3841666d03 chore(amazon-ca): add rtx 3070 cards (#1299) 2020-12-09 19:17:22 -05:00
Sebastian 2632386a5b feat(notification): add discord groups (#1211) 2020-12-09 14:54:51 -05:00
Jef LeCompte 9dc04b3638 chore: move linksBuilder log, add outOfStock amd-de 2020-12-09 11:30:56 -05:00
Jef LeCompte b2738370b4 chore(amazon): fix evga model 2020-12-09 10:32:42 -05:00
moiLegacy 54ef0ef995 chore(officedepot): add 3070 (#1280) 2020-12-09 02:23:43 -05:00
StanZha ba5c50495b chore(store): add rx6900xt for microcenter, newegg, bestbuy, amd (#1284) 2020-12-09 02:22:57 -05:00
Jef LeCompte 0e7de05fd2 docs: fix reference 2020-12-08 22:24:49 -05:00
Jef LeCompte 578027a36b chore(evga): add 3080 hydro copper
Resolve #965
2020-12-08 17:58:08 -05:00
Jef LeCompte 5e1dfc3568 fix(eprice): inStock selector
Fixes #1067

Co-authored-by: Maecenass
2020-12-08 17:47:02 -05:00
Zethus Suen 5955d10a7f feat(docs): add table sorting (#1258) 2020-12-08 17:22:33 -05:00
Jef LeCompte 64f55c1b86 chore: update labels 2020-12-08 17:09:36 -05:00
Jef LeCompte 1538937661 chore: fix issue template config 2020-12-08 17:06:58 -05:00
Jef LeCompte 46bed1ef3c chore: update issue templates 2020-12-08 17:02:00 -05:00
Jef LeCompte b56d214059 docs: fix hotlink
Fixes #1273
2020-12-08 16:51:13 -05:00
Jef LeCompte 625ae0ee53 docs: add rotating proxy note 2020-12-08 16:33:55 -05:00
Jef LeCompte d7602f3a0f docs: add discussion board 2020-12-08 15:54:26 -05:00
dtsulik b806e1bb9c chore(newegg): add powercolor red devil, red dragon (#1219) 2020-12-08 15:41:17 -05:00
Jef LeCompte 58f0a9c774 fix(bestbuy-ca): add outOfStock text
Resolves #1269
2020-12-08 15:18:05 -05:00
Jef LeCompte 48a46d0217 chore: remove husky, use include with tsconfig
Let CI handle linting
2020-12-08 15:07:47 -05:00
Jeremy Beasley 53eeff0bfc docs: fix typo in README (#1268) 2020-12-08 15:02:42 -05:00
Dylan Fontaine ac0bd2ac14 feat(store): add Toys R Us (#1257) 2020-12-08 15:01:08 -05:00
Jef LeCompte 0072dda90b fix(pushover): add expire and retry
Fixes #983
2020-12-08 14:20:15 -05:00
Jef LeCompte d56bcddb05 chore(store): add xbox to bestbuy-ca and amazon-ca
Resolves #982
2020-12-08 13:49:30 -05:00
Jef LeCompte 5aa4fdc7b9 chore: remove feature request and questions
Remove issue templates in favor of new https://github.com/jef/streetmerchant/discussions! This is beneficial so we can keep issues related to app development.
2020-12-08 13:01:45 -05:00
Jef LeCompte 60508e2ddb chore(deps): update twitch, husky, ts-node, xo 2020-12-08 11:50:04 -05:00
dependabot[bot] 4f7c9ed84f chore(deps-dev): bump @types/cheerio from 0.22.22 to 0.22.23 (#1251)
Bumps [@types/cheerio](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/cheerio) from 0.22.22 to 0.22.23.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/cheerio)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-08 11:47:47 -05:00
Luca Rinaldi e3eb38655a fix(store): italian store checks (#1212) 2020-12-08 11:37:30 -05:00
Dylan Fontaine b535b470ca feat(store): add Walmart (CA) (#1253) 2020-12-08 11:35:00 -05:00
Hangur 30bed2ac01 feat(store): add Megekko (#1216) 2020-12-08 08:36:20 -05:00
Darwin Do 84a6ff5973 chore(amazon): add 3060ti cards (#1229) 2020-12-07 12:01:41 -05:00
Simone Cavazzoni 84f2cb7d52 fix(amazon-it): maxPrice selector and links (#1239) 2020-12-07 12:00:27 -05:00
Jef LeCompte d5bd7e3db2 docs: update image link 2020-12-07 00:26:10 -05:00
Jef LeCompte 1f63e99804 fix(ci): mkdocs deps 2020-12-07 00:21:38 -05:00
Jef LeCompte 243109a4ff feat(docs): add mkdocs 2020-12-07 00:18:43 -05:00
github-actions[bot] bc2272e59a chore: release 3.2.0 (#980) 2020-12-06 00:35:45 -05:00
Michael Pietersen 888b5225b8 chore(bestbuy): 3060ti product links (#1197) 2020-12-06 00:34:03 -05:00
RDFurman 0c59d1e232 docs: add xfx brand (#1182) 2020-12-06 00:01:09 -05:00
Jef LeCompte 15ec12b0a3 feat(notification): add price to links (#1209)
fix(store): label selection ordering and pricing
fix(nvidia): deprecation notice removed outside of usa
fix(amazon): maxPrice selector

Resolves #1188
Resolves #673
Resolves #1187
2020-12-05 23:22:58 -05:00
Jef LeCompte f7b32e8ac5 feat(store): add custom labels for links (#1183)
Fixes #1132
Fixes #1163
2020-12-05 07:50:17 -05:00
Jef LeCompte 9bf33eceda chore: update issue templates 2020-12-04 18:53:50 -05:00
Jef LeCompte 14cbd5a05b fix(amazon-de): inStock selector
Fixes: #1178
2020-12-04 18:21:26 -05:00
Jef LeCompte ec0d9f50cb chore(deps): update 2020-12-04 17:54:34 -05:00
Jef LeCompte 4616f60766 ci: add stale cron job (#1176) 2020-12-04 17:52:43 -05:00
nazmi 36e38068d8 feat(store): add awd(uk), add 3060ti link builders (#1114) 2020-12-04 17:30:55 -05:00
Ben Turner ca5553cb20 fix(scan): links builder (#1161) 2020-12-04 17:29:12 -05:00
Michael Pietersen 34a8fd475a chore(microcenter): add 3060ti (#1171) 2020-12-04 17:28:27 -05:00
RDFurman 0569629dc8 chore(memex): add 3080 and 6800xt (#1168) 2020-12-04 17:23:55 -05:00
desigi 09f0236086 feat(store): add 3060ti to newegg-ca, canadacomputer, memoryexpress (#1172)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-04 17:21:20 -05:00
Jef LeCompte e67d97fe93 chore: update selectors, remove api lookup for now
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-04 17:05:28 -05:00
fnk93 75ee95b221 feat(store): add el corte ingles (#1107) 2020-12-04 10:49:53 -05:00
Darkgran1 3c727f1c9a chore(store): add 3060ti to link builders (#1156) 2020-12-04 10:46:43 -05:00
Sam Marshall 80e166c15d docs: add cd step (#1157) 2020-12-04 10:45:21 -05:00
jaw20 3b4fe78e95 chore(amazon): adds most available AIB cards (#1140) 2020-12-04 10:44:11 -05:00
dependabot[bot] ac8785d1e9 chore(deps): bump amannn/action-semantic-pull-request from v2.1.0 to v2.1.1 (#1150)
Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from v2.1.0 to v2.1.1.
- [Release notes](https://github.com/amannn/action-semantic-pull-request/releases)
- [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v2.1.0...153d429823cc133a83ab5d92065465a5c2f0d8b7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-04 01:26:16 -05:00
SamP301 06f3aafae6 fix(bestbuy-ca): model always indicating in stock (#1145) 2020-12-04 01:25:47 -05:00
jaw20 f2ae423fa8 fix(store): removes unnecessary newegg links from bestbuy (#1126)
Fixes #1119
2020-12-03 12:47:08 -05:00
clreinki cbad0846af chore(newegg): add 3060ti models (#1112) 2020-12-03 12:44:37 -05:00
trinityhades a3a94c19d9 chore(zotac): add 3080 amp holo (#1133) 2020-12-03 12:29:53 -05:00
Jef LeCompte 6fd023e81e fix(amazon): price and cart buttons
Resolves #1125

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-03 11:55:07 -05:00
Jef LeCompte e836acf1e9 docs: update COUNTRY information 2020-12-03 11:37:56 -05:00
Jef LeCompte 5bbdfa2abc fix(smythstoys): add out of stock label
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 17:47:06 -05:00
Jef LeCompte 1ed0593767 feat(store): add smythstoys
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 17:31:10 -05:00
Jef LeCompte cbc43304bf fix(amazon-de): remove xbox cart links
Fixes #1095

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 16:58:05 -05:00
Jef LeCompte feddac76d3 fix(newegg): maxPrice selector using used price
Fixes #1052

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 16:51:53 -05:00
Jef LeCompte 0e8774b1d0 chore(newegg): add big navi aibs
Part of #931

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 16:46:04 -05:00
Jef LeCompte 0e5edee683 chore(store): add big navi aibs
Resolves #931 #937 #1098

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 16:38:32 -05:00
fnk93 0b11238370 fix(store): add backoffStatusCodes and new captcha container (#1110) 2020-12-02 16:28:31 -05:00
fnk93 6de8c4a5ee feat(store): add amazon-de-warehouse (#1102) 2020-12-02 16:27:42 -05:00
fnk93 cf70f1ff4f feat(store): add spielegrotte (#1056) 2020-12-02 16:25:39 -05:00
Jef LeCompte a0a961aa5b chore(lint): ignore max 5 params
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 16:14:52 -05:00
fnk93 7d29ef80ba feat(store): add Medimax (#1057) 2020-12-02 16:08:53 -05:00
fnk93 e198e44613 fix(store): update euroFormat for expert and otto (#1108) 2020-12-02 16:08:09 -05:00
fnk93 f7b753334f chore(store): update eu stores (#1100) 2020-12-02 16:03:33 -05:00
Jef LeCompte 21e74cfe76 fix(walmart): instock container and add test:series
Related #1106

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 15:51:02 -05:00
Joseph Sortino ea456116da chore(bandh): add 3060ti (#1104) 2020-12-02 13:28:35 -05:00
dependabot[bot] a0a0ca8755 chore(deps-dev): bump @types/async from 3.2.4 to 3.2.5 (#1054)
Bumps [@types/async](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/async) from 3.2.4 to 3.2.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/async)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-02 13:19:28 -05:00
dependabot[bot] c26bd8f06a chore(deps): bump GoogleCloudPlatform/release-please-action from v2.9.3 to v2.10 (#1083)
Bumps [GoogleCloudPlatform/release-please-action](https://github.com/GoogleCloudPlatform/release-please-action) from v2.9.3 to v2.10.
- [Release notes](https://github.com/GoogleCloudPlatform/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleCloudPlatform/release-please-action/compare/v2.9.3...ea92f88c9a810e645f40f778ad87b21ffb3422ca)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-02 13:19:00 -05:00
Foxlet c5799fddc7 chore(zotac): add 3060ti, 3070 (#1094) 2020-12-02 13:18:49 -05:00
fnk93 af96c5f2e8 feat(store): add Otto (#1096) 2020-12-02 13:16:19 -05:00
GeorgSchessler 2fc018bbb2 chore(mediamarkt): add 3060ti (#1089) 2020-12-02 13:14:43 -05:00
GeorgSchessler a72a35c755 chore(saturn): add 3060ti (#1091) 2020-12-02 13:13:59 -05:00
fnk93 202698f917 feat(store): add expert (#1105) 2020-12-02 13:13:25 -05:00
Jef LeCompte d7f242780e feat(topachat): add maxPrice
Closes #1097

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-02 12:19:01 -05:00
Jef LeCompte b2f5c1a3ed feat(store): add argos with ps5
Updated env-example
Add max price for test series

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-01 23:56:15 -05:00
Jef LeCompte 29478bff2d feat(bestbuy-ca): add 3060ti cards
Update test matches

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-01 23:08:24 -05:00
Jef LeCompte beb50696fb chore: change 3060 to 3060ti
Add to `README`
Update test:series for bestbuy

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-12-01 22:44:33 -05:00
Mark Dietzer 490d44e1fd feat: add proxy rotation (settable per store) (#1026) 2020-12-01 22:25:48 -05:00
Shervin Mortazavi 65df944973 fix(bestbuy-ca): replace old evga xc3 ultra (#1058) 2020-12-01 18:59:08 -05:00
fnk93 ce43654847 chore(cyberport): remove xbox/ps5 (#1065) 2020-12-01 18:26:08 -05:00
petertdinh e9a39c4092 feat(bestbuy): add 3060 series (#1074) 2020-12-01 18:22:07 -05:00
DasGinger 4bccc6b407 dics: correct model values for xbox (#1051) 2020-11-30 23:34:25 -05:00
Jef LeCompte 37d62ebcd5 docs: punctuation 2020-11-30 20:38:25 -05:00
Jef LeCompte af080f376d docs: add more faq 2020-11-30 20:37:38 -05:00
Joseph Sortino 19eece18dc feat(store): add antonline store (#1042) 2020-11-30 17:01:09 -05:00
fnk93 1774afc1c3 feat(store): add Euronics DE (#1045) 2020-11-30 17:00:30 -05:00
fnk93 79a3f33150 feat(store): add Gamestop DE (#1046) 2020-11-30 17:00:03 -05:00
Marcel Zobus 796c2a52ac chore(amd-de): add rx6800xt (#1044) 2020-11-30 16:59:09 -05:00
fnk93 0b60d3cf9a chore(store): add xbox/ps5 to eu stores (#1047) 2020-11-30 16:58:27 -05:00
dependabot[bot] fb696bf85a chore(deps-dev): bump webpack from 5.6.0 to 5.9.0 (#1031)
Bumps [webpack](https://github.com/webpack/webpack) from 5.6.0 to 5.9.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.6.0...v5.9.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-30 12:12:58 -05:00
dependabot[bot] 0b8e0d498c chore(deps): bump @slack/web-api from 5.13.0 to 5.14.0 (#1032)
Bumps [@slack/web-api](https://github.com/slackapi/node-slack-sdk) from 5.13.0 to 5.14.0.
- [Release notes](https://github.com/slackapi/node-slack-sdk/releases)
- [Commits](https://github.com/slackapi/node-slack-sdk/compare/@slack/web-api@5.13.0...@slack/web-api@5.14.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-30 12:12:46 -05:00
MrMcChewy 8ecba2db96 chore(microcenter): add 3070 models (#1030) 2020-11-30 09:27:40 -05:00
xeaon eb176d1735 chore(caseking): add rx6800xt (#1028) 2020-11-30 09:25:36 -05:00
xeaon bea26450bf chore(alternate): add rx6800xt (#1027) 2020-11-30 09:20:38 -05:00
Foxlet 8c82705dd3 chore(amd): add rx6800 (#926) 2020-11-30 00:55:01 -05:00
Juan Francisco Lopez Jimenez feae978de9 feat(store): add wipoid store (#1018)
Co-authored-by: nakyl <nakyl@hotmail.com>
2020-11-30 00:54:06 -05:00
JP Confessor 5e6159b994 chore(bestbuy-ca): add ps5 console (#1020) 2020-11-30 00:52:51 -05:00
Luca Rinaldi 30a51a38be feat(store): add ePrice store (#1016)
feat: add ps5 max price
fix: typo of `MAX_PRICE_SERIES_CORSAIR_SF` on .env-example
2020-11-29 10:44:14 -05:00
Luca Rinaldi de7036c7cc feat(store): update the italian store links (#1002) 2020-11-28 21:58:00 -05:00
Yuheng Ouyang a79ce6f406 chore(store): add amd (ca) (#1006) 2020-11-28 21:55:25 -05:00
dependabot[bot] 0b4966e452 chore(deps-dev): bump @types/node from 14.14.9 to 14.14.10 (#946) 2020-11-28 12:16:13 -05:00
dependabot[bot] be48520469 chore(deps): bump twitch from 4.3.1 to 4.3.2 (#944) 2020-11-28 12:16:01 -05:00
dependabot[bot] d2efb91de4 chore(deps): bump mqtt from 4.2.5 to 4.2.6 (#947) 2020-11-28 12:15:39 -05:00
dependabot[bot] a519a79ee7 chore(deps): bump twitch-chat-client from 4.3.0 to 4.3.2 (#943) 2020-11-28 12:10:54 -05:00
dependabot[bot] 7db79345a0 chore(deps): bump GoogleCloudPlatform/release-please-action from v2.7.0 to v2.9.3 (#942) 2020-11-28 12:09:52 -05:00
Luca Rinaldi b28bf73157 docs: update supported stores (#981) 2020-11-28 12:07:40 -05:00
Yuheng Ouyang 11b6316371 chore(newegg-ca): ad amd rx 6000 aib cards (#930) 2020-11-28 12:07:13 -05:00
MrMcChewy 10ce2db9ae chore(microcenter): add Strix OC (#992) 2020-11-28 12:02:23 -05:00
joslynesser 364c6c25df feat(proxy): socks5 support (#933) 2020-11-27 14:18:23 -05:00
Jean-Sébastien TRILLE a8d9c033b6 chore(store): Added RX6800 series to ccl store (#935) 2020-11-27 14:15:00 -05:00
eddwatts 7a441b4b65 chore(store): add 3070 series currys (#948) 2020-11-27 14:13:33 -05:00
eddwatts 09238da69c chore(store): add 6800 & 6800xt cards to scan (#950) 2020-11-27 14:13:06 -05:00
eddwatts 4d8700e856 chore(store): add 6800 & 6800xt cards to ebuyer (#951) 2020-11-27 14:12:37 -05:00
eddwatts 1ee9d38b32 chore(store): add 6800 & 6800xt cards to overclockers (#952) 2020-11-27 14:12:08 -05:00
Rees Varney db18157a49 fix: related products being picked up on scan (#954) 2020-11-27 14:11:28 -05:00
Enrico Martelli 3286d624a1 chore(store): add amd-it store and RX 6800 XT (#974) 2020-11-27 14:09:31 -05:00
Luca Rinaldi f663579f3d feat(store): add some italian stores with ps5 links (#976) 2020-11-27 14:08:34 -05:00
dependabot[bot] 20e8746748 chore(deps): bump twitch-auth from 4.3.0 to 4.3.1 (#908)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-24 16:50:41 -05:00
dependabot[bot] d0839beffe chore(deps): bump twitch from 4.3.0 to 4.3.1 (#910)
Bumps [twitch](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.1/packages/twitch)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-24 16:45:55 -05:00
dependabot[bot] 07b6b340f9 chore(deps): bump GoogleCloudPlatform/release-please-action from v2.6.0 to v2.7.0 (#897)
Bumps [GoogleCloudPlatform/release-please-action](https://github.com/GoogleCloudPlatform/release-please-action) from v2.6.0 to v2.7.0.
- [Release notes](https://github.com/GoogleCloudPlatform/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleCloudPlatform/release-please-action/compare/v2.6.0...562cbbb6314482b22af9cd42cd3adf4159e4c705)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-24 16:45:19 -05:00
erikswain a99eecb461 fix(newegg): typo in 5800x url(#903) 2020-11-24 16:44:44 -05:00
David Gauch f7f0b08e30 chore(newegg): add cartUrl to AMD and Xbox items (#904) 2020-11-24 16:43:45 -05:00
David Gauch efddd01aa9 chore(walmart): add Corsair SF PSUs (#891) 2020-11-24 16:43:05 -05:00
David Gauch 0857b8a46e chore(walmart): add 5900x (#906) 2020-11-24 16:38:12 -05:00
Charles-Antoine Patenaude 67605a6e28 fix(memoryexpress): add backorder to outOfStock selector (#890) 2020-11-23 14:55:33 -05:00
dependabot[bot] 80826ba0bd chore(deps): bump dorny/paths-filter from v2.5.3 to v2.6.0 (#896)
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from v2.5.3 to v2.6.0.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/v2.5.3...eb75a1edc117d3756a18ef89958ee59f9500ba58)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-23 14:53:46 -05:00
Charles-Antoine Patenaude 06214eb4a8 fix(canadacomputers): add inStock selector, use english links (#889) 2020-11-23 14:53:07 -05:00
Chris Mendoza a62bd2e587 docs: add corsair and max price setting (#888) 2020-11-23 03:40:50 -05:00
David Gauch 4df57f578e chore(newegg): add Corsair SF PSUs (#892) 2020-11-23 03:39:12 -05:00
Jef LeCompte b4f34510d5 chore(ci): fix workflow syntax
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-22 12:03:14 -05:00
Jef LeCompte 429effb544 chore(ci): include docker build on dep change
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-22 12:00:53 -05:00
github-actions[bot] c2defe224a chore: release 3.1.0 (#774) 2020-11-22 11:57:58 -05:00
Chris Mendoza e552c9102d feat(store): add corsair sfx PSUs (#881) 2020-11-22 11:57:05 -05:00
Jef LeCompte 292e3603fd fix(store): generate links only for selected stores
Resolves: #694
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-22 11:53:17 -05:00
Jef LeCompte 85bbaf905e chore(xbox): add xbox series x
Closes: #836
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-22 11:34:30 -05:00
Armando D Jagucki 432d38bd5a chore(amazon): add big navi links (#880) 2020-11-22 10:08:22 -05:00
Sebastian 2d01cfddff feat(store): add captcha check to saturn and mediamarkt (#876) 2020-11-21 15:10:21 -05:00
Cristian 53739e05ab feat(store): add vsgamers (#767) 2020-11-21 13:28:01 -05:00
Jef LeCompte 9ad9793dc1 chore: update dependencies (#874)
Additional linting fixes

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-21 10:55:03 -05:00
dependabot[bot] f6f5c6bfe7 chore(deps): bump twitch-auth from 4.2.7 to 4.3.0 (#853)
Bumps [twitch-auth](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch-auth) from 4.2.7 to 4.3.0.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.0/packages/twitch-auth)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-21 10:37:24 -05:00
SolidPIPe 28c965d653 docs: remove duplicated models (#861) 2020-11-21 10:31:56 -05:00
Asier Eguibar 4b689cb94e feat(coolmod): add maxPrice (#862) 2020-11-21 10:31:36 -05:00
Barmaley13 c3f38fb2c9 chore: add more 3070 cards, reorder links (#872) 2020-11-21 10:29:10 -05:00
dependabot[bot] 239b5d3e8a chore(deps): bump twitch-chat-client from 4.2.7 to 4.3.0 (#856)
Bumps [twitch-chat-client](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch-chat-client) from 4.2.7 to 4.3.0.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.0/packages/twitch-chat-client)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-21 09:49:05 -05:00
dependabot[bot] 7694829dd6 chore(deps): bump twitch from 4.2.7 to 4.3.0 (#857)
Bumps [twitch](https://github.com/d-fischer/twitch/tree/HEAD/packages/twitch) from 4.2.7 to 4.3.0.
- [Release notes](https://github.com/d-fischer/twitch/releases)
- [Commits](https://github.com/d-fischer/twitch/commits/v4.3.0/packages/twitch)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-21 09:45:54 -05:00
Jef LeCompte d7921168cb chore: remove dependencies label 2020-11-19 18:28:51 -05:00
dependabot[bot] 9745190ee4 chore(deps-dev): bump webpack from 5.4.0 to 5.6.0 (#846)
Bumps [webpack](https://github.com/webpack/webpack) from 5.4.0 to 5.6.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.4.0...v5.6.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-19 18:08:50 -05:00
Jef LeCompte b5435643da chore: add quotes to .env-example
Based off #824

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-19 18:07:16 -05:00
Jef LeCompte af631c86f1 revert: correcting newline split for multiple user agents
Ref: f16a9fb331, #824
2020-11-19 18:05:50 -05:00
dependabot[bot] 5eb36a6cb7 chore(deps): bump node-pagerduty from 1.3.5 to 1.3.6 (#845)
Bumps [node-pagerduty](https://github.com/kmartin-215/node-pagerduty) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/kmartin-215/node-pagerduty/releases)
- [Commits](https://github.com/kmartin-215/node-pagerduty/compare/1.3.5...1.3.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-19 09:01:03 -05:00
xcaliber93 6f273305df feat(canadacomputers): add ryzen 5000 series (#842) 2020-11-19 09:00:46 -05:00
vmnt 6d292a11cd feat(newegg-ca): add big navi links (#843) 2020-11-19 08:59:37 -05:00
Rich Evans 89a762e2f5 feat(store): add amd rx 6000 series model (#832) 2020-11-18 20:14:27 -05:00
dependabot[bot] f9b617dd69 chore(deps): bump puppeteer from 5.4.1 to 5.5.0 (#819)
Bumps [puppeteer](https://github.com/puppeteer/puppeteer) from 5.4.1 to 5.5.0.
- [Release notes](https://github.com/puppeteer/puppeteer/releases)
- [Changelog](https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/puppeteer/puppeteer/compare/v5.4.1...v5.5.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-18 10:25:00 -05:00
dependabot[bot] 7fea7d58f0 chore(deps-dev): bump @types/node from 14.14.7 to 14.14.8 (#829)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.7 to 14.14.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-18 10:24:43 -05:00
joslynesser f16a9fb331 fix(config): correcting newline split for multiple user agents (#824) 2020-11-18 10:24:17 -05:00
VictorV 777c31b420 feat(notification): add product link to email and telegram (#816) 2020-11-18 10:23:31 -05:00
Matt Hayward 229daabb34 chore: add amd cpus to uk stores (#833) 2020-11-18 10:22:37 -05:00
Cristian d0ebffd056 feat(store): add 3070 models to pccomponentes & coolmod (#820) 2020-11-17 10:23:14 -05:00
Jef LeCompte 3feda151c5 docs: add cloud provider FAQ
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-16 11:28:53 -05:00
dependabot[bot] d41798ac23 chore(deps): bump dorny/paths-filter from v2.5.2 to v2.5.3 (#814)
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from v2.5.2 to v2.5.3.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/v2.5.2...d599443ba55e103985817f072734ef381431aeb4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-16 11:17:32 -05:00
James Hinton eb314afda5 feat(playstation): add outOfStock label (#812) 2020-11-16 11:12:35 -05:00
Jef LeCompte f377820894 chore: add question to issues template 2020-11-16 11:10:52 -05:00
Jef LeCompte 8933896c5c chore: remove duplicate chips
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-15 12:10:20 -05:00
Garret Picchioni 88a1303f73 chore(amazon): add zen 3 to us, es, and nl (#743) 2020-11-15 12:09:29 -05:00
Michael Vendivel 167713bb14 fix(amazon): add 5800x and 5600x (#802) 2020-11-15 12:05:14 -05:00
James Hinton 7c28c7f72b feat(store): add PlayStation store (#806) 2020-11-15 11:46:32 -05:00
Cristian b21b2440f7 chore(pccomponentes): add ryzen cpus (#756) 2020-11-14 22:05:06 -05:00
Michael Vendivel 63d550ca63 fix(bestbuy-ca): use proper selector (#801) 2020-11-14 22:02:49 -05:00
dependabot[bot] 8e1744c6b1 chore(deps): bump mqtt from 4.2.4 to 4.2.5 (#786)
Bumps [mqtt](https://github.com/mqttjs/MQTT.js) from 4.2.4 to 4.2.5.
- [Release notes](https://github.com/mqttjs/MQTT.js/releases)
- [Commits](https://github.com/mqttjs/MQTT.js/compare/v4.2.4...v4.2.5)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-13 11:17:47 -05:00
dependabot[bot] 0ed826fb5d chore(deps): bump nodemailer from 6.4.15 to 6.4.16 (#785)
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.4.15 to 6.4.16.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v6.4.15...v6.4.16)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-13 11:14:46 -05:00
dependabot[bot] d47a3e064e chore(deps-dev): bump @types/async from 3.2.3 to 3.2.4 (#787)
Bumps [@types/async](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/async) from 3.2.3 to 3.2.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/async)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-13 11:14:36 -05:00
Clinton Judy 501ea34a54 feat(asus): add backoff codes (#790) 2020-11-13 11:11:48 -05:00
Clinton Judy b60ad12cf2 chore(newegg): add 3080 vision oc (#791) 2020-11-13 11:10:31 -05:00
rodrigorodrigo ef2036b75d docs: small typo on canadacomputers (#779) 2020-11-12 22:44:59 -05:00
Jef LeCompte c38bebb49d feat(store): add topachat (#776)
Co-authored-by: Oguzhan YAGCI <oyagci@student.42.fr>
2020-11-12 08:50:31 -05:00
Zyde22 02d7c47c40 feat: add amazon-fr to stores. (#766) 2020-11-12 08:39:45 -05:00
Jef LeCompte efe0d64f06 revert: pipeline changes
Ref: 15e4520213
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-12 08:37:37 -05:00
rodrigorodrigo bd69e471f7 feat(store): support for canadacomputers (#772) 2020-11-12 08:24:15 -05:00
github-actions[bot] bdd74e5b16 chore: release 3.0.0 (#770)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-11 23:21:08 -05:00
Cristian 32702929a9 feat(coolmod): add zen 3 (#754) 2020-11-11 23:18:47 -05:00
Jef LeCompte b4de369ca8 docs: add checkout help
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-11 23:17:34 -05:00
Vincent ccb207abeb feat(discord): add cart link to embed (#762) 2020-11-11 23:15:10 -05:00
Jaden VanEckhout 841647c06c fix(walmart): ps5 digital url (#763)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-11 23:13:53 -05:00
HeitorLM 23d061b387 feat(store): support for kabum (amd and rtx 30 series) (#727)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-11 22:25:15 -05:00
Nathan Grebowiec a5249ecc7c feat: add option to disable auto add to cart (#759) 2020-11-11 20:56:45 -05:00
Jef LeCompte 0e730f4203 docs: update verbiage 2020-11-10 23:13:04 -05:00
gabriwong bc8c14c88d docs: add amazon error to faq (#760) 2020-11-10 23:11:34 -05:00
dependabot[bot] 5be33d045f chore(deps-dev): bump @types/puppeteer from 3.0.5 to 5.4.0 (#752)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-10 19:31:42 -05:00
Jef LeCompte d19dd5a404 refactor!: removed duplicated Model
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-10 17:50:43 -05:00
Jef LeCompte b1f1ea6ef0 docs: update README to reflect branches
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-10 17:19:39 -05:00
Jef LeCompte 15e4520213 chore: pipeline changes (#753) 2020-11-10 17:12:20 -05:00
Jef LeCompte 0904253cc6 refactor: add more types to Model, extract Brand
This is prep work for normalizing `Model`

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-10 10:53:24 -05:00
Jef LeCompte 318e626e78 feat: fix metadata in logging, lint prettier, typed Models (#747) 2020-11-10 10:38:14 -05:00
dependabot[bot] 0bf9ba2e18 chore(deps-dev): bump @types/node from 14.14.6 to 14.14.7 (#741)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.6 to 14.14.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-10 09:38:04 -05:00
Ben Wu 9f28fe5803 feat(notification): support for multiple phone numbers (#738) 2020-11-10 09:21:54 -05:00
Michael Vendivel ab1fddf20c feat(target): add additional selector for 'ship it' (#737) 2020-11-10 09:00:06 -05:00
BaelfireNightshd ff79d9e70d docs: add zen3 filter to SHOW_ONLY_SERIES (#742) 2020-11-10 08:59:04 -05:00
dependabot[bot] 050fd9faf6 chore(deps): bump nodemailer from 6.4.14 to 6.4.15 (#726)
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.4.14 to 6.4.15.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v6.4.14...v6.4.15)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-10 08:55:53 -05:00
James Hinton 0128718ba7 feat(store): add game store, add ps5 for uk stores (#736) 2020-11-10 08:55:27 -05:00
dependabot[bot] 037056156e chore(deps): bump dorny/paths-filter from v2.5.1 to v2.5.2 (#725)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-10 08:50:50 -05:00
dependabot[bot] d9692c7bbd chore(deps): bump GoogleCloudPlatform/release-please-action from v2.5.7 to v2.6.0 (#724)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-10 08:50:25 -05:00
Garret Picchioni 0754feccae fix(docker): copy web directory (#745) 2020-11-10 08:48:55 -05:00
SolidPIPe e8fd2f7c5b docs: add amd models (#746) 2020-11-10 08:48:09 -05:00
Vinh Nguyen 314f533f0b feat(store): add xbox series x and s (#732)
Co-authored-by: VictorV <velasquez.victor@gmail.com>
Co-authored-by: vinhnguyen <vinh.nguyen@venmo.com>
2020-11-10 08:47:15 -05:00
hiivin 4e086e9267 feat(galaxus): add zen 3 (#729) 2020-11-09 11:31:51 -05:00
Vincent dde9837829 feat(amazon): add more 3070s (#719)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-09 01:20:01 -05:00
serg06 25700567c5 feat(amazon-ca): add ps5 (#713)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-09 01:19:36 -05:00
Omelette Du Fromage c02241c752 feat: memoryexpress website support (#717)
Adding MemoryExpress website in Canada. Only track the online store
stock for now. Might add the stores stock later like microcenter.
Only track Ryzen 5000-series for now because RTX 3000-series is only
available in store backorder.

Co-authored-by: Omelette Du Fromage <lavrenti.rogoff@gmail.com>
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-09 01:18:49 -05:00
hiivin 38937f6880 feat(store): add arlt and amd-de (#721)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-09 01:16:58 -05:00
Jörg Battermann 0362bf8081 feat(mindfactory): add ryzen 5900x, 5950x (#720) 2020-11-09 01:14:16 -05:00
Jef LeCompte 815822f6f8 chore: add CODE_OF_CONDUCT.md 2020-11-07 13:01:47 -05:00
dependabot[bot] f9a6fd025a chore(deps): bump twilio from 3.50.0 to 3.51.0 (#699)
Bumps [twilio](https://github.com/twilio/twilio-node) from 3.50.0 to 3.51.0.
- [Release notes](https://github.com/twilio/twilio-node/releases)
- [Changelog](https://github.com/twilio/twilio-node/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-node/compare/3.50.0...3.51.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-07 12:56:32 -05:00
hiivin 2291b8eff5 feat(store): add ps5 to german stores (#715) 2020-11-07 12:55:42 -05:00
Andrew O'Brien 8a459056c5 feat(store): Adds AM3 to microcenter (#707)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-07 12:18:48 -05:00
Jef LeCompte 9320918335 docs: update docker notes
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-07 09:29:49 -05:00
Jef LeCompte 0d14500d5d feat: add production scripts and better Dockerfile
Closes: #710
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-07 09:26:17 -05:00
Michael Vendivel 42ef7cfdce feat(ps5): add console and digital edition (#709) 2020-11-06 16:42:05 -05:00
Nathan Grebowiec 0a680e977b feat: bring back ascii banner, but make it configurable (#703) 2020-11-06 16:39:34 -05:00
Jef LeCompte 19fd6895e7 docs: fix broken table
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-06 11:26:16 -05:00
Jef LeCompte e3fcc70bb3 docs: add philips hue video demo
Refs: https://github.com/jef/streetmerchant/pull/681#issuecomment-722716100
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-06 11:24:46 -05:00
hiivin 71d5cb4261 feat(store): add zen 3 to german stores (#702)
Co-authored-by: Florian Dahlmann <florian.dahlmann@gmx.de>
2020-11-06 09:39:37 -05:00
Jef LeCompte deb17d109f chore(philips-hue): remove unset warnings
Fixes #697

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-06 01:58:52 -05:00
serg06 760ddf5d85 feat(store): add zen 3 to more stores (#698) 2020-11-05 23:27:01 -05:00
Jef LeCompte 5db83484f3 fix: environment variables to match ryzen cpus
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 23:23:35 -05:00
Jef LeCompte 85208c4452 refactor: simplify max price
Ref: https://github.com/jef/streetmerchant/pull/696#issuecomment-722784373
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 23:19:37 -05:00
Nathan Grebowiec df3b10b9a5 feat(amd): add env vars and series filtering (#696)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 22:18:09 -05:00
Matthew c8a9b0ba3e feat(notification): add philips hue (#681)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
Co-authored-by: Nathan Banks <nathantb3@gmail.com>
2020-11-05 18:23:27 -05:00
Jef LeCompte 2955ea70ab fix: revert to 14.15.0 until 15 is stable for tsc
Fixes #691

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 18:04:48 -05:00
Jef LeCompte 7ec2894147 chore: bump node version
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 17:13:39 -05:00
Jef LeCompte 6924f362ba docs: update gif, change location
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 16:30:14 -05:00
Nathan Grebowiec 31a3d8f7e0 feat(amd): add 5950 config (#685) 2020-11-05 16:16:45 -05:00
Jef LeCompte a293f5e747 docs: update gif (#689)
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 16:13:09 -05:00
Jef LeCompte 2d3ea40a59 docs: update banner and readme
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 16:05:50 -05:00
github-actions[bot] 6861b3d052 chore: release 2.0.0 (#688)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-05 15:44:53 -05:00
Jef LeCompte 3f9b3c6017 chore!: update naming to streetmerchant
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 15:39:39 -05:00
Jef LeCompte 30720d3ca6 docs: fix alignment
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 15:28:02 -05:00
Jef LeCompte 0c550312bb chore: fix media (#687) 2020-11-05 15:23:38 -05:00
Jef LeCompte 30eb6a60cd docs: add logo
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-05 15:16:14 -05:00
dependabot[bot] 2737574b03 chore(deps-dev): bump webpack from 5.3.2 to 5.4.0 (#682)
Bumps [webpack](https://github.com/webpack/webpack) from 5.3.2 to 5.4.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.3.2...v5.4.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-11-04 15:35:02 -05:00
ElegyD d3c1a0233e chore(notebooksbilliger): add more FE links (#672)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-04 15:31:05 -05:00
Mark Dietzer 6ced13e993 fix(filterBrandsSeriesModels): always loop all stores (#680) 2020-11-03 19:42:17 -05:00
Jef LeCompte ec7be28f2e docs: update discord group tag
Resolves #679

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-03 19:30:49 -05:00
Jacob Williams 018784e653 feat(asus): realtime api (#675) 2020-11-03 17:29:06 -05:00
Karlo Delalic 3c5407f5cf feat(newegg-ca): realtime api (#674) 2020-11-03 17:26:57 -05:00
github-actions[bot] 0da1621595 chore: release 1.7.0 (#667)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-03 01:06:48 -05:00
Jacob Williams 5b3e95acdf feat: newegg realtime api (#664)
Co-authored-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-03 00:26:05 -05:00
Jef LeCompte 601742cf2c feat: add deprecation notices
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-03 00:11:27 -05:00
Thomas Wolfgruber e62eb72056 chore: add more 3070 cards to media markt and notebooksbilliger, fix false positives on media markt (#665) 2020-11-02 23:44:41 -05:00
Jef LeCompte 6cbe72118e docs: update freenode badge 2020-11-02 17:42:55 -05:00
Jef LeCompte bb3509f99b chore: add freenode chat button 2020-11-02 17:15:53 -05:00
Jef LeCompte 430f3ed220 chore: make COUNTRY lowercase
Fixes #662

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-02 15:27:33 -05:00
Jef LeCompte e00dafe8ff chore: bump dependencies
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-11-02 15:25:54 -05:00
Thomas Wolfgruber 137c0efdf0 chore(proshop-de): add 3070 cards (#659) 2020-11-01 21:52:29 -05:00
Garret Picchioni ffa2fdc700 chore(asus): add 3090 tuf oc (#657) 2020-11-01 21:52:05 -05:00
Andrew Wong a9f452f5a7 chore(newegg-ca): add evga ftw3 3080 and gigabyte vision oc 3080 (#656) 2020-11-01 21:51:34 -05:00
VictorV 1d2a33b1d7 fix(banner): add version to docker image (#649) 2020-10-30 15:42:17 -04:00
Jef LeCompte 493834b526 chore(newegg): add 3070s, include version in banner
Fixes #642

Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 13:15:21 -04:00
dependabot[bot] 1918fda5a2 chore(deps): bump GoogleCloudPlatform/release-please-action from v2.5.6 to v2.5.7 (#639)
Bumps [GoogleCloudPlatform/release-please-action](https://github.com/GoogleCloudPlatform/release-please-action) from v2.5.6 to v2.5.7.
- [Release notes](https://github.com/GoogleCloudPlatform/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleCloudPlatform/release-please-action/compare/v2.5.6...fc61d9d3dfb6339e3790181b6e6099dca3d907d9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-30 12:37:24 -04:00
dependabot[bot] 7038be2944 chore(deps): bump mqtt from 4.2.3 to 4.2.4 (#640)
Bumps [mqtt](https://github.com/mqttjs/MQTT.js) from 4.2.3 to 4.2.4.
- [Release notes](https://github.com/mqttjs/MQTT.js/releases)
- [Commits](https://github.com/mqttjs/MQTT.js/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-30 11:17:26 -04:00
Jef LeCompte 2fc584bdbd chore(amazon-de): add 3070 cards 2020-10-30 12:50:21 +00:00
Jef LeCompte 191bf8b2ff docs: update faq
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 00:33:35 -04:00
Jef LeCompte 3085dbcc7f docs: include help headers
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 00:28:47 -04:00
Jef LeCompte 92bb2ef915 docs: more collapsibles
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 00:23:32 -04:00
Jef LeCompte 2ec5baa37c docs: remove extra notifications
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 00:16:11 -04:00
Jef LeCompte 0fe3db9c99 docs: clean up README
Signed-off-by: Jef LeCompte <jeffreylec@gmail.com>
2020-10-30 00:12:43 -04:00
222 changed files with 34474 additions and 14954 deletions
+4 -4
View File
@@ -1,12 +1,12 @@
root = true root = true
[*] [*]
indent_style = tab indent_style = space
indent_size = 2
end_of_line = lf end_of_line = lf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[*.{yml,json}] [*.md]
indent_style = space indent_size = 4
indent_size = 2
-73
View File
@@ -1,73 +0,0 @@
# ** All configuration variables are optional **
# Read https://github.com/jef/nvidia-snatcher#customization for help on customizing this file
#############################################################################################
BROWSER_TRUSTED=
COUNTRY=
DESKTOP_NOTIFICATIONS=
DISCORD_NOTIFY_GROUP=
DISCORD_WEB_HOOK=
EMAIL_PASSWORD=
EMAIL_TO=
EMAIL_USERNAME=
HEADLESS=
IN_STOCK_WAIT_TIME=
LOG_LEVEL=
LOW_BANDWIDTH=
MAX_PRICE_SERIES_3070=
MAX_PRICE_SERIES_3080=
MAX_PRICE_SERIES_3090=
MICROCENTER_LOCATION=
MQTT_BROKER_ADDRESS=
MQTT_BROKER_PORT=
MQTT_CLIENT_ID=
MQTT_PASSWORD=
MQTT_QOS=
MQTT_TOPIC=
MQTT_USERNAME=
NVIDIA_ADD_TO_CART_ATTEMPTS=
NVIDIA_SESSION_TTL=
OPEN_BROWSER=
PAGE_BACKOFF_MIN=
PAGE_BACKOFF_MAX=
PAGE_SLEEP_MIN=
PAGE_SLEEP_MAX=
PAGE_TIMEOUT=
PAGERDUTY_INTEGRATION_KEY=
PAGERDUTY_SEVERITY=
PHONE_CARRIER=
PHONE_NUMBER=
PLAY_SOUND=
PROXY_ADDRESS=
PROXY_PORT=
PUSHBULLET=
PUSHOVER_TOKEN=
PUSHOVER_USER=
PUSHOVER_PRIORITY=
SCREENSHOT=
SHOW_ONLY_BRANDS=
SHOW_ONLY_MODELS=
SHOW_ONLY_SERIES=
SLACK_CHANNEL=
SLACK_TOKEN=
SMTP_ADDRESS=
SMTP_PORT=
STORES=
TELEGRAM_ACCESS_TOKEN=
TELEGRAM_CHAT_ID=
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_FROM_NUMBER=
TWILIO_TO_NUMBER=
TWITCH_ACCESS_TOKEN=
TWITCH_CHANNEL=
TWITCH_CLIENT_ID=
TWITCH_CLIENT_SECRET=
TWITCH_REFRESH_TOKEN=
TWITTER_ACCESS_TOKEN_KEY=
TWITTER_ACCESS_TOKEN_SECRET=
TWITTER_CONSUMER_KEY=
TWITTER_CONSUMER_SECRET=
TWITTER_TWEET_TAGS=
USER_AGENT=
WEB_PORT=
+2
View File
@@ -0,0 +1,2 @@
build/
docs/
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "./node_modules/gts/"
}
+33
View File
@@ -0,0 +1,33 @@
---
name: "\U0001F41B Bug report"
about: Report a bug for this project
title: ''
labels: ''
assignees: ''
---
## Expected Behavior
<!-- Tell us what should happen -->
## Current Behavior
<!-- Tell us what happens instead of the expected behavior -->
## Steps to Reproduce
<!-- Provide a link to a live example, or an unambiguous set of steps to reproduce this bug. -->
<!-- Include code to reproduce, if relevant -->
## Environment
- OS:
<!-- Put your dotenv within backticks below. Be sure to remove any secrets/passwords. -->
```dotenv
```
## Logs
<!-- Provide a brief log -->
-18
View File
@@ -1,18 +0,0 @@
---
name: 🐛 Bug report
about: Report a bug for this project
title: ''
labels: 'type: bug'
assignees: jef
---
### Description
<!-- Describe the bug here. -->
<!-- Please be as detailed as possible. -->
<!-- Include OS, screenshots and console outputs. -->
### Possible solution
<!-- Describe the possible solution here. -->
+11
View File
@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 💡 Have an idea for a new feature?
url: https://github.com/jef/streetmerchant/discussions
about: Create a new idea discussion!
- name: 🙇 Need help with streetmerchant?
url: https://github.com/jef/streetmerchant/discussions
about: Create a new help discussion if it hasn't been asked before!
- name: 💬 Want to talk with others that use streetmerchant?
url: https://discord.gg/gbVY4vB9JF
about: Join our Discord to hangout and talk shop!
-16
View File
@@ -1,16 +0,0 @@
---
name: 🚀 Feature request
about: Suggest a feature for this project
title: ''
labels: 'type: enhancement'
assignees: jef
---
### Description
<!-- Describe the feature here. -->
### Possible solution
<!-- Describe the possible solution here. -->
-6
View File
@@ -4,17 +4,11 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
labels:
- "dependencies"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
labels:
- "dependencies"
- package-ecosystem: "npm" - package-ecosystem: "npm"
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
labels:
- "dependencies"
-40
View File
@@ -1,40 +0,0 @@
name: cd
on:
push:
branches:
- main
paths-ignore:
- '**.md'
jobs:
cd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: GoogleCloudPlatform/release-please-action@v2.5.6
id: release
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: simple
package-name: nvidia-snatcher
- name: login into github package registry
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
- name: build nightly docker image
if: ${{ ! steps.release.outputs.release_created }}
run: |
docker build \
-t "ghcr.io/${GITHUB_REPOSITORY}:${GITHUB_SHA:0:7}" \
-t "ghcr.io/${GITHUB_REPOSITORY}:nightly" .
- name: publish nightly
if: ${{ ! steps.release.outputs.release_created }}
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
- name: build latest docker image
if: ${{ steps.release.outputs.release_created }}
run: |
docker build \
-t "ghcr.io/${GITHUB_REPOSITORY}:${TAG_NAME}" \
-t "ghcr.io/${GITHUB_REPOSITORY}:latest" .
env:
TAG_NAME: ${{ steps.release.outputs.tag_name }}
- name: publish latest
if: ${{ steps.release.outputs.release_created }}
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
+24 -19
View File
@@ -1,40 +1,45 @@
name: ci name: Continuous Integration
on: on:
pull_request: pull_request:
branches: branches:
- main - main
paths-ignore:
- '**.md'
jobs: jobs:
build-lint: build-lint:
name: Build and lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - name: Checkout repository
- uses: actions/setup-node@v2.1.2 uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2.1.4
with: with:
node-version: 14 node-version: 14.15.4
- uses: actions/cache@v2 - name: Setup build cache
uses: actions/cache@v2
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node- restore-keys: ${{ runner.os }}-node-
- name: Add problem matcher - name: Install dependencies
run: echo "::add-matcher::.github/xo-problem-matcher.json" run: npm ci
- name: Pull dependencies - name: Compile TypeScript
run: | run: npm run compile
npm ci - name: Run linter
npm run build run: npm run lint
npm run lint
build-docker: build-docker:
name: Build Docker image
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - name: Checkout repository
- uses: dorny/paths-filter@v2.5.1 uses: actions/checkout@v2
- name: Run paths filter
uses: dorny/paths-filter@v2.7.0
id: filter id: filter
with: with:
filters: | filters: |
docker: build:
- 'Dockerfile' - 'Dockerfile'
- name: Build image - 'package*.json'
if: steps.filter.outputs.docker == 'true' - name: Build Docker image
if: steps.filter.outputs.build == 'true'
run: docker build . run: docker build .
+20
View File
@@ -0,0 +1,20 @@
name: Documentation
on:
push:
branches:
- main
jobs:
build-deploy:
name: Build and publish documentation
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install Python packages
run: pip install mkdocs-material mkdocs-git-revision-date-plugin mkdocs-macros-plugin
- name: Build and publish documentation
run: mkdocs gh-deploy --force
+21
View File
@@ -0,0 +1,21 @@
name: Nightly Release
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch: {}
jobs:
build-release:
name: Build and release Docker image
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Login into GitHub Container Registry
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
- name: Build Docker image
run: |
docker build \
-t "ghcr.io/${GITHUB_REPOSITORY}:${GITHUB_SHA:0:7}" \
-t "ghcr.io/${GITHUB_REPOSITORY}:nightly" .
- name: Release Docker image
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
@@ -1,4 +1,4 @@
name: pr-lint name: Pull Request Lint
on: on:
pull_request_target: pull_request_target:
types: types:
@@ -7,9 +7,11 @@ on:
- reopened - reopened
- synchronize - synchronize
jobs: jobs:
main: pull-request-lint:
name: Lint pull request
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: amannn/action-semantic-pull-request@v2.1.0 - name: Lint pull request
uses: amannn/action-semantic-pull-request@v3.1.0
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+34
View File
@@ -0,0 +1,34 @@
name: Release
on:
push:
branches:
- main
jobs:
build-tag-release:
name: Build, tag, and release Docker image
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup release please
uses: google-github-actions/release-please-action@v2.15
id: release
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: simple
changelog-path: docs/changelog.md
package-name: streetmerchant
- name: Login into GitHub Container Registry
if: ${{ steps.release.outputs.release_created }}
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
- name: Build Docker image
if: ${{ steps.release.outputs.release_created }}
run: |
docker build \
-t "ghcr.io/${GITHUB_REPOSITORY}:${TAG_NAME}" \
-t "ghcr.io/${GITHUB_REPOSITORY}:latest" .
env:
TAG_NAME: ${{ steps.release.outputs.tag_name }}
- name: Release Docker image
if: ${{ steps.release.outputs.release_created }}
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
+26
View File
@@ -0,0 +1,26 @@
name: Stale Checker
on:
schedule:
- cron: '0 0 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
close-issue-message: ${{ env.CLOSE_MESSAGE }}
close-pr-message: ${{ env.CLOSE_MESSAGE }}
days-before-stale: 30
days-before-close: 5
exempt-issue-labels: ${{ env.EXEMPT_LABEL }}
exempt-pr-labels: ${{ env.EXEMPT_LABEL }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-label: ${{ env.STALE_LABEL }}
stale-pr-label: ${{ env.STALE_LABEL }}
stale-issue-message: ${{ env.STALE_MESSAGE }}
stale-pr-message: ${{ env.STALE_MESSAGE }}
env:
CLOSE_MESSAGE: 'This issue has been closed because it is stale. Reopen if necessary.'
EXEMPT_LABEL: 'status: needs discussion,priority: low,priority: medium, priority: high,status: help wanted,status: in progress'
STALE_LABEL: 'status: stale'
STALE_MESSAGE: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
+4 -3
View File
@@ -2,11 +2,12 @@
.vs/ .vs/
.vscode/ .vscode/
build/ build/
coverage/
node_modules/ node_modules/
.env* .env
.*env dotenv
!.env-example *.proxies
success-*.png success-*.png
*.wav *.wav
+1 -1
View File
@@ -1 +1 @@
15.0.1 14.15.4
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
...require('gts/.prettierrc.json')
}
+441 -166
View File
@@ -1,231 +1,506 @@
# Changelog # Changelog
## [1.6.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.5.0...v1.6.0) (2020-10-29) ## [3.4.0](https://www.github.com/jef/streetmerchant/compare/v3.3.0...v3.4.0) (2021-01-17)
### Features ### Features
* add series to Discord webhook ([#618](https://www.github.com/jef/nvidia-snatcher/issues/618)) ([273d058](https://www.github.com/jef/nvidia-snatcher/commit/273d05841451ed896f1d505bcd24f2230a143d3a)) * add browser opening to test:notification ([f87053c](https://www.github.com/jef/streetmerchant/commit/f87053cb02e04b3cb2c0cf253187a9e9857c9858))
* **api:** add rudimentary web control panel ([#183](https://www.github.com/jef/nvidia-snatcher/issues/183)) ([373d1a9](https://www.github.com/jef/nvidia-snatcher/commit/373d1a973865b14b5753517aa70eabf85b136d94)) * add c8 and mocha for testing ([f87053c](https://www.github.com/jef/streetmerchant/commit/f87053cb02e04b3cb2c0cf253187a9e9857c9858))
* **store:** add founders editions to notebooksbilliger.de ([#593](https://www.github.com/jef/nvidia-snatcher/issues/593)) ([2e5db7a](https://www.github.com/jef/nvidia-snatcher/commit/2e5db7af04e6ce79660477d8deb6636ec2e7845e)) * add command parameter to set custom dotenv conf ([#1590](https://www.github.com/jef/streetmerchant/issues/1590)) ([b03d242](https://www.github.com/jef/streetmerchant/commit/b03d24217f8ff5a56ddf19c019d10b48afec813f))
* **store:** add max price containers to multiple stores ([#579](https://www.github.com/jef/nvidia-snatcher/issues/579)) ([f9c4c25](https://www.github.com/jef/nvidia-snatcher/commit/f9c4c258748ffd3735f1e7385bde15b6112a1ca7)) * add redis ([#1390](https://www.github.com/jef/streetmerchant/issues/1390)) ([fb82526](https://www.github.com/jef/streetmerchant/commit/fb82526a427e503fff1f1cf56b091ff0c8a5a96e))
* **store:** add new cards to german web shops ([#597](https://www.github.com/jef/nvidia-snatcher/issues/597)) ([699de57](https://www.github.com/jef/nvidia-snatcher/commit/699de573f6579b59ba2c65cc2bf4dd6ccba3c863)) * **asus:** add outOfStock label ([#1653](https://www.github.com/jef/streetmerchant/issues/1653)) ([d0a4667](https://www.github.com/jef/streetmerchant/commit/d0a4667a643398d836652642b993107ed05619d8)), closes [#368](https://www.github.com/jef/streetmerchant/issues/368)
* **store:** Add PCComponentes and Amazon-ES Stores. ([#558](https://www.github.com/jef/nvidia-snatcher/issues/558)) ([062201f](https://www.github.com/jef/nvidia-snatcher/commit/062201f092c7a271202f27e7297b8eb9d7269c02)) * **azerty:** add ryzen 5000 series ([#878](https://www.github.com/jef/streetmerchant/issues/878)) ([ca59777](https://www.github.com/jef/streetmerchant/commit/ca59777917777401affc5b72a68238983f286237))
* **store:** support for azerty ([#557](https://www.github.com/jef/nvidia-snatcher/issues/557)) ([58416e1](https://www.github.com/jef/nvidia-snatcher/commit/58416e1994006cc2e4055937c675e0f9191f6339)) * **caseking:** add 3060ti/3070 cards / add missing 3080/3090 cards ([#1715](https://www.github.com/jef/streetmerchant/issues/1715)) ([b2ebac3](https://www.github.com/jef/streetmerchant/commit/b2ebac36c078d8001501d45e3a2bbf5f91a1a489))
* **store:** support for coolmod ([#605](https://www.github.com/jef/nvidia-snatcher/issues/605)) ([c1dda4f](https://www.github.com/jef/nvidia-snatcher/commit/c1dda4f9871988fad43d79f3bfe65f7c7860b9f7)) * **galaxus:** update selector, add out of stock check ([#1607](https://www.github.com/jef/streetmerchant/issues/1607)) ([c9cda1e](https://www.github.com/jef/streetmerchant/commit/c9cda1e4e597c7103a32c32c9e5a79824ad44de5))
* add `meta` to logger ([#437](https://www.github.com/jef/nvidia-snatcher/issues/437)) ([ae6bc86](https://www.github.com/jef/nvidia-snatcher/commit/ae6bc86bcb75c154a2a68adda324f34f18281700)) * **lookup:** add max price for xbox ([f34a808](https://www.github.com/jef/streetmerchant/commit/f34a808451b735c384f4b763cedd816c85ab7abc)), closes [#1436](https://www.github.com/jef/streetmerchant/issues/1436)
* add alternate.nl support ([#552](https://www.github.com/jef/nvidia-snatcher/issues/552)) ([aca6523](https://www.github.com/jef/nvidia-snatcher/commit/aca65233339ddbbcc1dbd06f9011d6d44c6650cf)) * **lookup:** add protection against infinite recursion for Cloudflare ([#1505](https://www.github.com/jef/streetmerchant/issues/1505)) ([1cf618c](https://www.github.com/jef/streetmerchant/commit/1cf618c1c12d3ab94688139a8410bed181af3eb2)), closes [#1459](https://www.github.com/jef/streetmerchant/issues/1459) [#1490](https://www.github.com/jef/streetmerchant/issues/1490)
* add asus-de store and asus 3080 tuf/oc to amazon-de ([#436](https://www.github.com/jef/nvidia-snatcher/issues/436)) ([b4d8733](https://www.github.com/jef/nvidia-snatcher/commit/b4d8733d1823e2fa5d3a1b80d2d4218bfa737cd7)) * **lookup:** handle Cloudflare DDoS protection ([#1434](https://www.github.com/jef/streetmerchant/issues/1434)) ([f86a825](https://www.github.com/jef/streetmerchant/commit/f86a8259f37f0ed25b00e243b29aa28c3e68bdff)), closes [#1297](https://www.github.com/jef/streetmerchant/issues/1297)
* add caseking and proshop-de store ([#521](https://www.github.com/jef/nvidia-snatcher/issues/521)) ([1aaa102](https://www.github.com/jef/nvidia-snatcher/commit/1aaa102c06281b60da593d04ced01f8b20a37a3b)) * **proshop-de:** add proshop-de inStock selector ([#1633](https://www.github.com/jef/streetmerchant/issues/1633)) ([9c2ea8d](https://www.github.com/jef/streetmerchant/commit/9c2ea8dbe91f46e24eae1e9e717164d99f94d0e1))
* add coolblue store ([#482](https://www.github.com/jef/nvidia-snatcher/issues/482)) ([5c61333](https://www.github.com/jef/nvidia-snatcher/commit/5c61333df00c0c30f04e4aced01a498c5816ad58)) * **proxy:** fallback to a global proxy list ([#1388](https://www.github.com/jef/streetmerchant/issues/1388)) ([be1953b](https://www.github.com/jef/streetmerchant/commit/be1953b2069fce72969904c1bc18055df73f4b6b))
* add german stores ([#462](https://www.github.com/jef/nvidia-snatcher/issues/462)) ([85a07dc](https://www.github.com/jef/nvidia-snatcher/commit/85a07dc0dc6a8dfe2aba1d4ea3e4cde6ec083086)) * **pushover:** add screenshot to push notification if available ([#1552](https://www.github.com/jef/streetmerchant/issues/1552)) ([f9a3d03](https://www.github.com/jef/streetmerchant/commit/f9a3d03f356d7ed2072772b86c7776f62dcd32b5))
* add incognito mode ([#534](https://www.github.com/jef/nvidia-snatcher/issues/534)) ([2b6457e](https://www.github.com/jef/nvidia-snatcher/commit/2b6457e8409658b843204fa0aeafb00d48f9e53e)) * remove stale user agents, use top 50 ([6e2a162](https://www.github.com/jef/streetmerchant/commit/6e2a16238c54bc448f3ae5243ef8729f384ea59b))
* add link series to error message for better context ([#265](https://www.github.com/jef/nvidia-snatcher/issues/265)) ([332b4a8](https://www.github.com/jef/nvidia-snatcher/commit/332b4a8246320e458729c0b58c310d290df12530)) * **store:** add `johnlewis` store, add `shopto` store ([#1481](https://www.github.com/jef/streetmerchant/issues/1481)) ([ec8d357](https://www.github.com/jef/streetmerchant/commit/ec8d3571cfbbd3a028aed9b5650eb8a52c9af587))
* Add PagerDuty Integration ([#565](https://www.github.com/jef/nvidia-snatcher/issues/565)) ([11ee0bf](https://www.github.com/jef/nvidia-snatcher/commit/11ee0bf1a3e2d0d550d2731f9de9e178c382ea1f)) * **store:** add equippr & futurex for DE region ([#1501](https://www.github.com/jef/streetmerchant/issues/1501)) ([5b70ff1](https://www.github.com/jef/streetmerchant/commit/5b70ff14cb9ab5e0a72922624d54b40bb0642bcd))
* add proshop-dk ([#524](https://www.github.com/jef/nvidia-snatcher/issues/524)) ([dc2fcf5](https://www.github.com/jef/nvidia-snatcher/commit/dc2fcf5ab4dba8be459bd5aa6a41e3e097205d45)) * **store:** add GPU and CPU support for Vuugo ([#1555](https://www.github.com/jef/streetmerchant/issues/1555)) ([8ab6e1f](https://www.github.com/jef/streetmerchant/commit/8ab6e1f1d801c3ae52987fe9e8550adbe2015ea6))
* add support for multiple browser user agents ([#547](https://www.github.com/jef/nvidia-snatcher/issues/547)) ([10a81dc](https://www.github.com/jef/nvidia-snatcher/commit/10a81dcbd54557652537cb641cbbd727d39e34e5)) * **store:** add more italian sites ([#1701](https://www.github.com/jef/streetmerchant/issues/1701)) ([cb898c7](https://www.github.com/jef/streetmerchant/commit/cb898c7923ce8a45548807571e734ad232ce0004))
* add uk stores ([#455](https://www.github.com/jef/nvidia-snatcher/issues/455)) ([b9b6b55](https://www.github.com/jef/nvidia-snatcher/commit/b9b6b55c29d11f48b683816e5b8c1cab127ed5fd)) * **store:** add pcking and acompc ([#1470](https://www.github.com/jef/streetmerchant/issues/1470)) ([beee355](https://www.github.com/jef/streetmerchant/commit/beee35556376056b31d6719fb090ce58b7ea985f))
* allow filtering per model by a specific series ([#595](https://www.github.com/jef/nvidia-snatcher/issues/595)) ([a42418f](https://www.github.com/jef/nvidia-snatcher/commit/a42418f814dcd91354c136288d4c6a24e03a168d)) * **store:** add SG Location for Amazon and Newegg ([#1600](https://www.github.com/jef/streetmerchant/issues/1600)) ([ef926d2](https://www.github.com/jef/streetmerchant/commit/ef926d2282cedaef38bc3d4d427820f4aa65dc8d))
* optional per store min and max page sleep time ([#576](https://www.github.com/jef/nvidia-snatcher/issues/576)) ([503d76f](https://www.github.com/jef/nvidia-snatcher/commit/503d76f3c7d01368fc978af4ab02924d3d036ac0)) * **store:** addition of several australian sites ([#1651](https://www.github.com/jef/streetmerchant/issues/1651)) ([2fa8937](https://www.github.com/jef/streetmerchant/commit/2fa893795f21535e1799116843e0668b669835ab))
* **notification:** add `to` field for email ([#327](https://www.github.com/jef/nvidia-snatcher/issues/327)) ([8828dd1](https://www.github.com/jef/nvidia-snatcher/commit/8828dd15cd08959cd434bd256e8eac474dd17c49)) * **store:** specify links to navigate to between product searches ([#1542](https://www.github.com/jef/streetmerchant/issues/1542)) ([0982774](https://www.github.com/jef/streetmerchant/commit/09827741aec2158e88c19fd6b0156c32736671c8))
* **store:** add ttl for `scan` ([#555](https://www.github.com/jef/nvidia-snatcher/issues/555)) ([4847725](https://www.github.com/jef/nvidia-snatcher/commit/4847725d3a54d2f4dd0c349ff0ad80eb4bc4e9e3)) * **twilio:** add support to have multiple numbers ([#1450](https://www.github.com/jef/streetmerchant/issues/1450)) ([83508bc](https://www.github.com/jef/streetmerchant/commit/83508bc5ea509aac0742c525a6434ef8f8001899))
* add rog strix oc to amazon-de ([#471](https://www.github.com/jef/nvidia-snatcher/issues/471)) ([e5909c5](https://www.github.com/jef/nvidia-snatcher/commit/e5909c532da1c8b731e9835bffd8f31b76550d4d)) * update Docker and ci ([f87053c](https://www.github.com/jef/streetmerchant/commit/f87053cb02e04b3cb2c0cf253187a9e9857c9858))
* add support for specifying smtp server ([#458](https://www.github.com/jef/nvidia-snatcher/issues/458)) ([160ae37](https://www.github.com/jef/nvidia-snatcher/commit/160ae37d7bee4f0323cb939566d586f1300aece6)) * **vsgamers:** add maxPrice selector([#1682](https://www.github.com/jef/streetmerchant/issues/1682)) ([84382de](https://www.github.com/jef/streetmerchant/commit/84382def6f23b1e8b1ad8c14fb4f423f32a35eb7))
* allow multiple microcenter locations ([#487](https://www.github.com/jef/nvidia-snatcher/issues/487)) ([2b0eab6](https://www.github.com/jef/nvidia-snatcher/commit/2b0eab656d81314ce7d05064662ec138407550c3)) * **web:** properly set `for` attribute for labels ([#1626](https://www.github.com/jef/streetmerchant/issues/1626)) ([c0638d2](https://www.github.com/jef/streetmerchant/commit/c0638d2e4b923abacaf81fb09fd80948cd5e7ce9))
* clear cookies and cache ([#515](https://www.github.com/jef/nvidia-snatcher/issues/515)) ([1f89945](https://www.github.com/jef/nvidia-snatcher/commit/1f89945c5746befb2131381a358efdf8ac530e0c)), closes [#417](https://www.github.com/jef/nvidia-snatcher/issues/417)
* max price per series ([#451](https://www.github.com/jef/nvidia-snatcher/issues/451)) ([8adc07a](https://www.github.com/jef/nvidia-snatcher/commit/8adc07a03e411dd536bebfdc7270db4bbf8ddb34))
* mqtt alerts ([#538](https://www.github.com/jef/nvidia-snatcher/issues/538)) ([68ff5bf](https://www.github.com/jef/nvidia-snatcher/commit/68ff5bf836c63c8e14d02c06777e02e64a6a0f38))
* twitch chat notification, multiple telegram chat ids and german web shop overhaul ([#528](https://www.github.com/jef/nvidia-snatcher/issues/528)) ([675f13a](https://www.github.com/jef/nvidia-snatcher/commit/675f13abb892d1158c92c41e3d57049313a5e0b8))
* **docker:** add docker and publish images to ghcr ([#411](https://www.github.com/jef/nvidia-snatcher/issues/411)) ([c857985](https://www.github.com/jef/nvidia-snatcher/commit/c857985a6d3736287976caf5b173f19046306465))
* **notification:** add at&t prepaid carrier ([#425](https://www.github.com/jef/nvidia-snatcher/issues/425)) ([eb9d082](https://www.github.com/jef/nvidia-snatcher/commit/eb9d082d178a42e35789ba822cfae7b35c0413c1))
* **notification:** add pushover priority setting ([#186](https://www.github.com/jef/nvidia-snatcher/issues/186)) ([f277172](https://www.github.com/jef/nvidia-snatcher/commit/f2771721914a20619833df8ccb2ac44298687b4d))
* **notification:** add Twillio notification provider ([#344](https://www.github.com/jef/nvidia-snatcher/issues/344)) ([f2f8d81](https://www.github.com/jef/nvidia-snatcher/commit/f2f8d81498d1acfb9359f4a690962042ec20d166))
* **store:** add `pny` ([#295](https://www.github.com/jef/nvidia-snatcher/issues/295)) ([f6760d3](https://www.github.com/jef/nvidia-snatcher/commit/f6760d3c65d60eae9e4b1e0fdba34e814f446a4c))
* **store:** add 3090s to amazon-ca ([#274](https://www.github.com/jef/nvidia-snatcher/issues/274)) ([e992cf4](https://www.github.com/jef/nvidia-snatcher/commit/e992cf4db85f045fc8d03c9b93286fb72bad1061))
* **store:** add additional cards to all stores ([#286](https://www.github.com/jef/nvidia-snatcher/issues/286)) ([d25a643](https://www.github.com/jef/nvidia-snatcher/commit/d25a643425020fa3f7cd48972360ede17501afeb))
* **store:** add amazon cards and `cartUrl`s ([#284](https://www.github.com/jef/nvidia-snatcher/issues/284)) ([d69189f](https://www.github.com/jef/nvidia-snatcher/commit/d69189f12c893fb6d88b198d802ff8e36a69bc88))
* **store:** add asus strix oc to asus store ([#385](https://www.github.com/jef/nvidia-snatcher/issues/385)) ([e55398e](https://www.github.com/jef/nvidia-snatcher/commit/e55398e789d52def6e15d1e5e10f56cdf5ea5bea))
* **store:** add evga 3090 to newegg canada ([#396](https://www.github.com/jef/nvidia-snatcher/issues/396)) ([313d176](https://www.github.com/jef/nvidia-snatcher/commit/313d176848a25f183334db8926ac0ec445a2c481))
* **store:** add ftw3 ultra to microcenter ([#448](https://www.github.com/jef/nvidia-snatcher/issues/448)) ([5109227](https://www.github.com/jef/nvidia-snatcher/commit/5109227e8899f57b828b157309a76c397c872559))
* **store:** add gamestop ([#390](https://www.github.com/jef/nvidia-snatcher/issues/390)) ([7148451](https://www.github.com/jef/nvidia-snatcher/commit/7148451b66e97f4f7dcdcc86ce06ba8712211bd5))
* **store:** add models to bestbuy ([#421](https://www.github.com/jef/nvidia-snatcher/issues/421)) ([4085136](https://www.github.com/jef/nvidia-snatcher/commit/4085136269b00f6bc5c8414836de8310dfec4166))
* **store:** add rog-strix-3080 to newegg-ca ([#489](https://www.github.com/jef/nvidia-snatcher/issues/489)) ([207bc41](https://www.github.com/jef/nvidia-snatcher/commit/207bc411ed240cd9150e018b21e735ba08a4d134))
* add `norway` to `nvidia-api` ([#304](https://www.github.com/jef/nvidia-snatcher/issues/304)) ([eda6c85](https://www.github.com/jef/nvidia-snatcher/commit/eda6c85fc03a70c5933308e96c572a480bb6c8a0))
* configurable status code behaviours ([#340](https://www.github.com/jef/nvidia-snatcher/issues/340)) ([3b7487e](https://www.github.com/jef/nvidia-snatcher/commit/3b7487e97ac9d93344403f50153f2de6243b1f0d))
* enhanced lookup behaviour ([#270](https://www.github.com/jef/nvidia-snatcher/issues/270)) ([b868d1a](https://www.github.com/jef/nvidia-snatcher/commit/b868d1a4833a8ec5ac1c79481530d75cd0c4b01e))
* in stock wait time per link now ([c7a716f](https://www.github.com/jef/nvidia-snatcher/commit/c7a716f981976a76afe61a4d985bd6fe4343595b))
* low bandwidth mode ([#294](https://www.github.com/jef/nvidia-snatcher/issues/294)) ([0aa7ab5](https://www.github.com/jef/nvidia-snatcher/commit/0aa7ab596c907ce72c188eb4b1acdee088307437))
* max price filtering ([#383](https://www.github.com/jef/nvidia-snatcher/issues/383)) ([fd294d2](https://www.github.com/jef/nvidia-snatcher/commit/fd294d2baa06a1c0a68852497889a0412dea492e))
* **store:** adds aorus master 3080 to newegg ([#402](https://www.github.com/jef/nvidia-snatcher/issues/402)) ([fddc002](https://www.github.com/jef/nvidia-snatcher/commit/fddc0021d36e4d0a9dacccc546da8260684f0eeb))
* retry logic for nvidia session token and adding to cart ([#347](https://www.github.com/jef/nvidia-snatcher/issues/347)) ([1bac1b9](https://www.github.com/jef/nvidia-snatcher/commit/1bac1b928d401a819698848f3367edf54836b26f))
* support for proxy server ([#352](https://www.github.com/jef/nvidia-snatcher/issues/352)) ([fdcd787](https://www.github.com/jef/nvidia-snatcher/commit/fdcd787f91f26229db23e2291e8922b947007902))
* **store:** nvidia debug card for "product details" page ([#337](https://www.github.com/jef/nvidia-snatcher/issues/337)) ([5b8d774](https://www.github.com/jef/nvidia-snatcher/commit/5b8d774b7c7d31d6ba6fc43be3ea7b16a87d2e49))
### Bug Fixes ### Bug Fixes
* `amazon.{nl,de}` test urls ([#345](https://www.github.com/jef/nvidia-snatcher/issues/345)) ([589fbbc](https://www.github.com/jef/nvidia-snatcher/commit/589fbbcd34393ceb2bd7c0a8ac391c54e14a21be)) * **acompc:** false positives ([#1699](https://www.github.com/jef/streetmerchant/issues/1699)) ([0a1198b](https://www.github.com/jef/streetmerchant/commit/0a1198b69c4e7b22fcf9c9d0ed94ff51da4f8bce))
* `envOrNumber` behavior ([#364](https://www.github.com/jef/nvidia-snatcher/issues/364)) ([7d8897c](https://www.github.com/jef/nvidia-snatcher/commit/7d8897cd9fb9ae0db796fd85da3f2b9d1a9f73af)) * **amazon-de-warehouse:** update wrong maxPrice selector ([#1514](https://www.github.com/jef/streetmerchant/issues/1514)) ([90fb430](https://www.github.com/jef/streetmerchant/commit/90fb430b712aa6a89227a17d37a83380326db21b))
* `nvidia-api` ([#314](https://www.github.com/jef/nvidia-snatcher/issues/314)) ([8d8e5b5](https://www.github.com/jef/nvidia-snatcher/commit/8d8e5b587d2279a95d3e7837a99bea8c5990a477)) * **bandh:** asus cards / out of stock check added ([#1670](https://www.github.com/jef/streetmerchant/issues/1670)) ([b821eab](https://www.github.com/jef/streetmerchant/commit/b821eab273f3d8d4cecc1642467dbbad63f4e763))
* add `amazon-nl`, captcha `amazon-de`, add ftw3 `newegg` ([#293](https://www.github.com/jef/nvidia-snatcher/issues/293)) ([a2983eb](https://www.github.com/jef/nvidia-snatcher/commit/a2983eb54c419ba3a56abf80d316ea136a05e0fa)) * **bestbuy:** shorter pageview urls and missing carturl links ([#1613](https://www.github.com/jef/streetmerchant/issues/1613)) ([8faf320](https://www.github.com/jef/streetmerchant/commit/8faf3202e79825de5289659435c5f93b4e892086)), closes [#1610](https://www.github.com/jef/streetmerchant/issues/1610)
* add status code `429` to bandh `backOffStatusCodes` ([#404](https://www.github.com/jef/nvidia-snatcher/issues/404)) ([7a981e7](https://www.github.com/jef/nvidia-snatcher/commit/7a981e745673f2b12d48d7eed71fc34a6e4ba5b2)) * **computeruniverse:** false positives ([#1698](https://www.github.com/jef/streetmerchant/issues/1698)) ([e0849c4](https://www.github.com/jef/streetmerchant/commit/e0849c4dc2427a9f8be1927847a1fb2609a24600))
* add support for stores label text to have uppercase letters ([#526](https://www.github.com/jef/nvidia-snatcher/issues/526)) ([5ea7cc4](https://www.github.com/jef/nvidia-snatcher/commit/5ea7cc4ca45c506d2b98d4b643b44ca4ede1d7a9)) * disable redis if not configured ([6bc7737](https://www.github.com/jef/streetmerchant/commit/6bc7737ef04e5592e19b0b6a76e5fb0cd4b048df)), closes [#1516](https://www.github.com/jef/streetmerchant/issues/1516)
* asus store links ([#573](https://www.github.com/jef/nvidia-snatcher/issues/573)) ([f6db348](https://www.github.com/jef/nvidia-snatcher/commit/f6db3489b8b8a737dfc425880703928d5bc8916d)) * **galaxus:** maxPrice selector ([#1469](https://www.github.com/jef/streetmerchant/issues/1469)) ([7a5bc22](https://www.github.com/jef/streetmerchant/commit/7a5bc22ba8cede51311b80182c18fb0227532cd2))
* bestbuy label container selector precision ([#491](https://www.github.com/jef/nvidia-snatcher/issues/491)) ([cbc3b0b](https://www.github.com/jef/nvidia-snatcher/commit/cbc3b0b025469e9882ba8267f18f909c08c6c931)) * **galaxus:** update selector ( 14.01.2020 07:00 ) ([#1664](https://www.github.com/jef/streetmerchant/issues/1664)) ([a768eb4](https://www.github.com/jef/streetmerchant/commit/a768eb4cf54f81657532ae0c5e00588cc167eae2))
* corrected norway locales ([#356](https://www.github.com/jef/nvidia-snatcher/issues/356)) ([d2476dd](https://www.github.com/jef/nvidia-snatcher/commit/d2476ddb08606545b32b9676e2d299d57ec5cb6a)) * **galaxus:** update selector ([#1578](https://www.github.com/jef/streetmerchant/issues/1578)) ([ad5bd55](https://www.github.com/jef/streetmerchant/commit/ad5bd55c1ad9f54c9c1aa7ae875bd430d6304fac))
* cyclical dependencies ([ed970fc](https://www.github.com/jef/nvidia-snatcher/commit/ed970fc397210eb6ff684c7e82c79eb685a5d0d9)), closes [#468](https://www.github.com/jef/nvidia-snatcher/issues/468) * **galaxus:** update selector ([#1599](https://www.github.com/jef/streetmerchant/issues/1599)) ([445a007](https://www.github.com/jef/streetmerchant/commit/445a00728fec1c8b6bded8583d4a6712c195143b))
* denver `microcenter` name ([#296](https://www.github.com/jef/nvidia-snatcher/issues/296)) ([349f55d](https://www.github.com/jef/nvidia-snatcher/commit/349f55d3603517b5741fce6ac42b29141816ea79)) * **galaxus:** update selector ([#1705](https://www.github.com/jef/streetmerchant/issues/1705)) ([2120d29](https://www.github.com/jef/streetmerchant/commit/2120d2901d03ae2238bd56d46e0c43dcb16af70e))
* dutch stores components ([#513](https://www.github.com/jef/nvidia-snatcher/issues/513)) ([586029c](https://www.github.com/jef/nvidia-snatcher/commit/586029c92aa19bdddcc85b7a837bb7a16bb1d28d)) * **lookup:** check out of stock before price ([#1422](https://www.github.com/jef/streetmerchant/issues/1422)) ([02d29c3](https://www.github.com/jef/streetmerchant/commit/02d29c3c64a7976622da6cbdf099b76b455082d0))
* gamestop false positives ([#395](https://www.github.com/jef/nvidia-snatcher/issues/395)) ([d3bb507](https://www.github.com/jef/nvidia-snatcher/commit/d3bb507edca112124115ed88fb03cf14440d95ef)) * **lookup:** remove mobile versions of user agent ([96ae818](https://www.github.com/jef/streetmerchant/commit/96ae818e84c99d0597e0ddd7b5ecfe1a0615d1ed))
* in stock wait time ([#325](https://www.github.com/jef/nvidia-snatcher/issues/325)) ([07bd246](https://www.github.com/jef/nvidia-snatcher/commit/07bd246e876cd27df1b5019af5ee8613bb5368f0)), closes [#315](https://www.github.com/jef/nvidia-snatcher/issues/315) * **newegg:** false positives (all stores) ([#1714](https://www.github.com/jef/streetmerchant/issues/1714)) ([3f191bb](https://www.github.com/jef/streetmerchant/commit/3f191bbd00e7474fbef71ddd28955672835ef1a0))
* max price getter updated to match .env ([#516](https://www.github.com/jef/nvidia-snatcher/issues/516)) ([32f114b](https://www.github.com/jef/nvidia-snatcher/commit/32f114b23527ee247c84c081a2cd0264de3b4847)), closes [#514](https://www.github.com/jef/nvidia-snatcher/issues/514) [#510](https://www.github.com/jef/nvidia-snatcher/issues/510) * properly pass array entries as separate indices ([#1502](https://www.github.com/jef/streetmerchant/issues/1502)) ([0c6e2d5](https://www.github.com/jef/streetmerchant/commit/0c6e2d587d81041b07a561b3f53b8b1ebcb9f843))
* page sleep ([#586](https://www.github.com/jef/nvidia-snatcher/issues/586)) ([a2af30b](https://www.github.com/jef/nvidia-snatcher/commit/a2af30b70334cdbbfa51140d5de23a2d6b8429c8)), closes [#594](https://www.github.com/jef/nvidia-snatcher/issues/594) [#576](https://www.github.com/jef/nvidia-snatcher/issues/576) * **proxy:** fix requests with proxies ([#1408](https://www.github.com/jef/streetmerchant/issues/1408)) ([f65df4c](https://www.github.com/jef/streetmerchant/commit/f65df4ce56891c368dab8dd6fe85a584cf9e6f49))
* remove 3090 drid for DK/FI regions ([#361](https://www.github.com/jef/nvidia-snatcher/issues/361)) ([f1d22d1](https://www.github.com/jef/nvidia-snatcher/commit/f1d22d1684c8e70f09acd9978e6ea802d7224c8b)) * **proxy:** update proxy module ([#1451](https://www.github.com/jef/streetmerchant/issues/1451)) ([ab03702](https://www.github.com/jef/streetmerchant/commit/ab037029b654f5e169a97c9e7a2c4dfa6cf1e768)), closes [#1437](https://www.github.com/jef/streetmerchant/issues/1437)
* trim strings from comma-separated values ([#472](https://www.github.com/jef/nvidia-snatcher/issues/472)) ([f7ed865](https://www.github.com/jef/nvidia-snatcher/commit/f7ed86506b4e76d5bc20787068be83a44ec485b5)) * **store:** link builder in UK stores ([#1486](https://www.github.com/jef/streetmerchant/issues/1486)) ([eb59dc3](https://www.github.com/jef/streetmerchant/commit/eb59dc3433c54027695fb68cfe69b1d90fce3fec))
* typo in maxPrice for 3090 ([#496](https://www.github.com/jef/nvidia-snatcher/issues/496)) ([e073590](https://www.github.com/jef/nvidia-snatcher/commit/e0735903b7b4b0d542dbbd76b9a860b1eca24e96)) * **store:** Update 30 series links and models for store.asus.com ([#1645](https://www.github.com/jef/streetmerchant/issues/1645)) ([20bea85](https://www.github.com/jef/streetmerchant/commit/20bea85e411277f70b987675b53055b69d450e0f)), closes [#1637](https://www.github.com/jef/streetmerchant/issues/1637)
* update gigabyte model `vision oc` ([#550](https://www.github.com/jef/nvidia-snatcher/issues/550)) ([4fefe22](https://www.github.com/jef/nvidia-snatcher/commit/4fefe22a907094fa39af5b4f2e3f8f3fe6897115)) * **store:** update missing/mislabeled cards for Canadian retailers ([#1574](https://www.github.com/jef/streetmerchant/issues/1574)) ([082776c](https://www.github.com/jef/streetmerchant/commit/082776cfca740ac0a22736f791c62705a62185be))
* update new additions with web panel and sleep operations ([#606](https://www.github.com/jef/nvidia-snatcher/issues/606)) ([61a23fe](https://www.github.com/jef/nvidia-snatcher/commit/61a23fe9782223dc067dbc8251c3b09adbca0a43)) * **store:** update out of stock detection for MediaMarkt and Saturn ([#1549](https://www.github.com/jef/streetmerchant/issues/1549)) ([4f86d24](https://www.github.com/jef/streetmerchant/commit/4f86d2462e5d1eba6a7d7839585c0fe8c1b70da5)), closes [#1545](https://www.github.com/jef/streetmerchant/issues/1545)
* update pushbullet import to match package ([#637](https://www.github.com/jef/nvidia-snatcher/issues/637)) ([d7360f7](https://www.github.com/jef/nvidia-snatcher/commit/d7360f71ef1a076713246ad2832ca58e7163e492)) * **webui:** handling of file serving ([#1383](https://www.github.com/jef/streetmerchant/issues/1383)) ([445689e](https://www.github.com/jef/streetmerchant/commit/445689efc49bf8edb0b5a027611f02ea0d0f126f))
* **env:** default `LOG_LEVEL` ([9636572](https://www.github.com/jef/nvidia-snatcher/commit/9636572c7de36f7ac6800ba31ac60fcd7bd2fd03)) * **wipoid:** added 3090/3080/3070/3060ti/ryzen store items ([#1683](https://www.github.com/jef/streetmerchant/issues/1683)) ([be54171](https://www.github.com/jef/streetmerchant/commit/be541713a8855f18b5102917751842e514796e00))
* **notification:** discord false triggers ([#346](https://www.github.com/jef/nvidia-snatcher/issues/346)) ([3b90bbb](https://www.github.com/jef/nvidia-snatcher/commit/3b90bbbe5d751003a39823e9113eaee8cbfcf1a2))
* **notification:** sms subject output ([#298](https://www.github.com/jef/nvidia-snatcher/issues/298)) ([03755d5](https://www.github.com/jef/nvidia-snatcher/commit/03755d5eb117ac14797e0180c74f50b401e50cb5)) ## [3.3.0](https://www.github.com/jef/streetmerchant/compare/v3.2.0...v3.3.0) (2020-12-13)
* **notifications:** twilio client creation ([#349](https://www.github.com/jef/nvidia-snatcher/issues/349)) ([5414b24](https://www.github.com/jef/nvidia-snatcher/commit/5414b249a6f938615cfad02ca22c171a5f86e127))
* **store:** gamestop `label.inStock` ([9e7976d](https://www.github.com/jef/nvidia-snatcher/commit/9e7976df5778a953c4fb6ca7553773655c1f4127))
* **store:** pccomponents model normalization ([#563](https://www.github.com/jef/nvidia-snatcher/issues/563)) ([699e77d](https://www.github.com/jef/nvidia-snatcher/commit/699e77d960b17dcb50378975a1913b0badeabfcc)) ### Features
* updating amazon test model card to an in stock product ([#492](https://www.github.com/jef/nvidia-snatcher/issues/492)) ([81daa7c](https://www.github.com/jef/nvidia-snatcher/commit/81daa7c5596ab23bd9e6aac29fa63ee09e136827))
* **config:** `MAX_PRICE` quotations ([#426](https://www.github.com/jef/nvidia-snatcher/issues/426)) ([b7e5941](https://www.github.com/jef/nvidia-snatcher/commit/b7e5941a9598a09afabbb79c5636b768345009a3)) * **discord:** dynamic currency symbol ([#1328](https://www.github.com/jef/streetmerchant/issues/1328)) ([cccfde2](https://www.github.com/jef/streetmerchant/commit/cccfde245affc11506c69d1ef6c30c09953307d4))
* **store:** container names on `nvidia` ([#333](https://www.github.com/jef/nvidia-snatcher/issues/333)) ([772de90](https://www.github.com/jef/nvidia-snatcher/commit/772de900a1386e9635d139e152fe86366404ded4)) * **docs:** add mkdocs ([243109a](https://www.github.com/jef/streetmerchant/commit/243109a4ffdfe1d1efe961af0b5cf28fd7e6ef1d))
* **store:** update `inStock` and `maxPrice` for newegg, newegg-ca ([#433](https://www.github.com/jef/nvidia-snatcher/issues/433)) ([628cab1](https://www.github.com/jef/nvidia-snatcher/commit/628cab1b605e4363c8dd5ad43476292ecb12db74)), closes [#400](https://www.github.com/jef/nvidia-snatcher/issues/400) * **docs:** add table sorting ([#1258](https://www.github.com/jef/streetmerchant/issues/1258)) ([5955d10](https://www.github.com/jef/streetmerchant/commit/5955d10a7f2106c5ae1275fadacf2945626ca008))
* **lookup:** use random user agents ([#1335](https://www.github.com/jef/streetmerchant/issues/1335)) ([b599c23](https://www.github.com/jef/streetmerchant/commit/b599c23b51735212e5369ce03a44bbd1bccafa42))
* **notification:** add discord groups ([#1211](https://www.github.com/jef/streetmerchant/issues/1211)) ([2632386](https://www.github.com/jef/streetmerchant/commit/2632386a5b99f3b23166e88f92af809f0036a6b7))
* **notification:** add sound player executable option ([#1301](https://www.github.com/jef/streetmerchant/issues/1301)) ([8d19231](https://www.github.com/jef/streetmerchant/commit/8d192317badfd71a7cd8f0115ba9e6fc951c1874))
* **playstation:** add queuing selector ([#1173](https://www.github.com/jef/streetmerchant/issues/1173)) ([67b19a7](https://www.github.com/jef/streetmerchant/commit/67b19a7a8b3dead5f5ab9575ee2b4f09924ce851))
* **store:** add darkhero motherboard to asus and microcenter ([#1336](https://www.github.com/jef/streetmerchant/issues/1336)) ([29175c7](https://www.github.com/jef/streetmerchant/commit/29175c77a8fcbc082c944b057a919dfcc22ba606))
* **store:** add EBGames ([#1281](https://www.github.com/jef/streetmerchant/issues/1281)) ([27cfb94](https://www.github.com/jef/streetmerchant/commit/27cfb94de8d9ccef3c7fc76b250aee17d7c80257))
* **store:** add Irish store variants ([#1373](https://www.github.com/jef/streetmerchant/issues/1373)) ([f70998f](https://www.github.com/jef/streetmerchant/commit/f70998f0d9a6cdfbc59fb31fecb87f801b0b3037))
* **store:** add Megekko ([#1216](https://www.github.com/jef/streetmerchant/issues/1216)) ([30bed2a](https://www.github.com/jef/streetmerchant/commit/30bed2ac016e9e543f67b1098819a484bc1394c3))
* **store:** add several Australian stores, add some 3080 brands/models ([#1367](https://www.github.com/jef/streetmerchant/issues/1367)) ([579cb97](https://www.github.com/jef/streetmerchant/commit/579cb97a0d151cc374a37493b043ba4a399b55db))
* **store:** add Toys R Us ([#1257](https://www.github.com/jef/streetmerchant/issues/1257)) ([ac0bd2a](https://www.github.com/jef/streetmerchant/commit/ac0bd2ac14d686a0f30931e885da65a1d7af6856))
* **store:** add Walmart (CA) ([#1253](https://www.github.com/jef/streetmerchant/issues/1253)) ([b535b47](https://www.github.com/jef/streetmerchant/commit/b535b470cad38af034889b4d27578b20136e166d))
### Bug Fixes
* **adblock:** proxy another function to produce less errors ([#1379](https://www.github.com/jef/streetmerchant/issues/1379)) ([eb70076](https://www.github.com/jef/streetmerchant/commit/eb700762a4eee3a802bd81f0fb62e76243027c42))
* **amazon-it:** maxPrice selector and links ([#1239](https://www.github.com/jef/streetmerchant/issues/1239)) ([84f2cb7](https://www.github.com/jef/streetmerchant/commit/84f2cb7d52fac7c3dbdd31318a51330e25808784))
* **amazon-nl:** inStock selector ([b6964b0](https://www.github.com/jef/streetmerchant/commit/b6964b02f38c947fd476d86de35d5983e5b229dd)), closes [#1366](https://www.github.com/jef/streetmerchant/issues/1366)
* **bestbuy-ca:** add outOfStock text ([58f0a9c](https://www.github.com/jef/streetmerchant/commit/58f0a9c7740c46f3d820c8765dee5b0fc8516353)), closes [#1269](https://www.github.com/jef/streetmerchant/issues/1269)
* **bestbuy-ca:** update selectors to help false positives ([#1278](https://www.github.com/jef/streetmerchant/issues/1278)) ([0525119](https://www.github.com/jef/streetmerchant/commit/0525119b9bae47425a6c01720d6a1ea6ab8e6a02)), closes [#895](https://www.github.com/jef/streetmerchant/issues/895)
* **ci:** mkdocs deps ([1f63e99](https://www.github.com/jef/streetmerchant/commit/1f63e9980499ac567845473dc48e51cab78c838e))
* **config:** disable docker by default ([dca916b](https://www.github.com/jef/streetmerchant/commit/dca916b64e9ac2d05d5e6af19e5466b8a0623ed5))
* **config:** remove quotes ([ef452d8](https://www.github.com/jef/streetmerchant/commit/ef452d8e586536a5039ee532d655d2951d551ac3))
* **discord:** notification groupings ([ad0b2fe](https://www.github.com/jef/streetmerchant/commit/ad0b2fe525d6403735ddcbf4ef55b91eb36ac10a))
* **docker:** run in docker, and build scripts for docker ([#1291](https://www.github.com/jef/streetmerchant/issues/1291)) ([c74ea28](https://www.github.com/jef/streetmerchant/commit/c74ea28014ee0d827ea216083844f92e30f142c9))
* **eprice:** inStock selector ([5e1dfc3](https://www.github.com/jef/streetmerchant/commit/5e1dfc35680029620a1de7bc7a523140f2dae8af)), closes [#1067](https://www.github.com/jef/streetmerchant/issues/1067)
* **newegg:** dedupe nitro+ models ([#1300](https://www.github.com/jef/streetmerchant/issues/1300)) ([7329c6e](https://www.github.com/jef/streetmerchant/commit/7329c6ede0a5ab6d644b30ac878f4e7da11e43a8)), closes [#1230](https://www.github.com/jef/streetmerchant/issues/1230)
* **newegg:** price selector and mobile inStock ([c3beedc](https://www.github.com/jef/streetmerchant/commit/c3beedced82141e6bbb0735b3edb7c573907aa7a)), closes [#1356](https://www.github.com/jef/streetmerchant/issues/1356)
* **pushover:** add `expire` and `retry` ([0072dda](https://www.github.com/jef/streetmerchant/commit/0072dda90b637b93647cf3a35dc612cf43d89445)), closes [#983](https://www.github.com/jef/streetmerchant/issues/983)
* **store:** update UK stores ([#1372](https://www.github.com/jef/streetmerchant/issues/1372)) ([02825d0](https://www.github.com/jef/streetmerchant/commit/02825d009bd028f6dcdca02e2c155e77a7df8654))
* `.env` backwards compatibility ([9b7c7e2](https://www.github.com/jef/streetmerchant/commit/9b7c7e2881d756909af191094bda435ca7ef7e9b))
* add setRequestInterception ([#1312](https://www.github.com/jef/streetmerchant/issues/1312)) ([a44621f](https://www.github.com/jef/streetmerchant/commit/a44621f8f50cac9ba6614b0f89320d210370047a)), closes [#826](https://www.github.com/jef/streetmerchant/issues/826)
* **store:** italian store checks ([#1212](https://www.github.com/jef/streetmerchant/issues/1212)) ([e3eb386](https://www.github.com/jef/streetmerchant/commit/e3eb38655a3cefb85c4dbd573494955e06c72f71))
### Reverts ### Reverts
* reduce false-positive during ci/cd ([79b9bfe](https://www.github.com/jef/nvidia-snatcher/commit/79b9bfe9a83858117f7a58b4b8b1a1569d80c442)) * allow users to still use `USER_AGENT` ([3386e8f](https://www.github.com/jef/streetmerchant/commit/3386e8f50da27a800c5289c3b6bd7a1f76e77a49))
## [1.5.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.4.0...v1.5.0) (2020-09-24) ## [3.2.0](https://www.github.com/jef/streetmerchant/compare/v3.1.0...v3.2.0) (2020-12-06)
### Features ### Features
* filter models ([#261](https://www.github.com/jef/nvidia-snatcher/issues/261)) ([e1b34a9](https://www.github.com/jef/nvidia-snatcher/commit/e1b34a9ccfa45fa1a11da9af9074059b6084904b)) * **bestbuy:** add 3060 series ([#1074](https://www.github.com/jef/streetmerchant/issues/1074)) ([e9a39c4](https://www.github.com/jef/streetmerchant/commit/e9a39c40925736a2126f6138c369710989904d1d))
* **log:** colors for console logs ([#207](https://www.github.com/jef/nvidia-snatcher/issues/207)) ([0ad67fe](https://www.github.com/jef/nvidia-snatcher/commit/0ad67fe20453898ce0a6b5faff00062735411119)) * **bestbuy-ca:** add 3060ti cards ([29478bf](https://www.github.com/jef/streetmerchant/commit/29478bff2d27d780cc6142526f3970b4a87290bc))
* **notification:** add desktop notifications ([#140](https://www.github.com/jef/nvidia-snatcher/issues/140)) ([722eaf3](https://www.github.com/jef/nvidia-snatcher/commit/722eaf3cd680c4600b79f842c6c5acdb9e51ad71)) * **notification:** add price to links ([#1209](https://www.github.com/jef/streetmerchant/issues/1209)) ([15ec12b](https://www.github.com/jef/streetmerchant/commit/15ec12b0a3a95716243bfd06f6d41959bff7c36e)), closes [#1188](https://www.github.com/jef/streetmerchant/issues/1188) [#673](https://www.github.com/jef/streetmerchant/issues/673) [#1187](https://www.github.com/jef/streetmerchant/issues/1187)
* **notification:** add pushbullet, add url with notifications ([#226](https://www.github.com/jef/nvidia-snatcher/issues/226)) ([74490ea](https://www.github.com/jef/nvidia-snatcher/commit/74490eae3ab30de7d7a708d5dd970e070f27f2ea)) * **proxy:** socks5 support ([#933](https://www.github.com/jef/streetmerchant/issues/933)) ([364c6c2](https://www.github.com/jef/streetmerchant/commit/364c6c25dfe9dcbeb29cb20cb46e9e8dcc2fe86b))
* **notification:** twitter integration ([#224](https://www.github.com/jef/nvidia-snatcher/issues/224)) ([908ed35](https://www.github.com/jef/nvidia-snatcher/commit/908ed358826f9de530f5892ded1a54964a304d15)) * **store:** add 3060ti to newegg-ca, canadacomputer, memoryexpress ([#1172](https://www.github.com/jef/streetmerchant/issues/1172)) ([09f0236](https://www.github.com/jef/streetmerchant/commit/09f0236086c59b25ebe611041bf063d536e3cc3d))
* **store:** add `bannedSeller` label for stores ([#173](https://www.github.com/jef/nvidia-snatcher/issues/173)) ([71c6774](https://www.github.com/jef/nvidia-snatcher/commit/71c6774511f7ba13d34d2e40b69abf52d06e6225)) * **store:** add amazon-de-warehouse ([#1102](https://www.github.com/jef/streetmerchant/issues/1102)) ([6de8c4a](https://www.github.com/jef/streetmerchant/commit/6de8c4a5eec8d66fb47d87e309866ba18f3e28c7))
* **store:** add amazon-de ([#167](https://www.github.com/jef/nvidia-snatcher/issues/167)) ([8a70f14](https://www.github.com/jef/nvidia-snatcher/commit/8a70f147438584cc334710bc66220d05eb32fcbd)) * **store:** add antonline store ([#1042](https://www.github.com/jef/streetmerchant/issues/1042)) ([19eece1](https://www.github.com/jef/streetmerchant/commit/19eece18dccd4489e1e441b92061fc3b5743e4cd))
* **store:** add bestbuy.ca ([#229](https://www.github.com/jef/nvidia-snatcher/issues/229)) ([22fd22f](https://www.github.com/jef/nvidia-snatcher/commit/22fd22fe743d3e286eae3430aecd6e7a0a5de8c0)) * **store:** add argos with ps5 ([b2f5c1a](https://www.github.com/jef/streetmerchant/commit/b2f5c1a3ed93cfd56e575ec634d235565a17b6bc))
* **store:** add evga eu ([#172](https://www.github.com/jef/nvidia-snatcher/issues/172)) ([605bdd7](https://www.github.com/jef/nvidia-snatcher/commit/605bdd7ca73c585734f6c5df1a86f4fbfbff9163)) * **store:** add awd(uk), add 3060ti link builders ([#1114](https://www.github.com/jef/streetmerchant/issues/1114)) ([36e3806](https://www.github.com/jef/streetmerchant/commit/36e38068d8cd284c741d4906d5ba5fe8cff85d24))
* **store:** add evga model ([#220](https://www.github.com/jef/nvidia-snatcher/issues/220)) ([190388c](https://www.github.com/jef/nvidia-snatcher/commit/190388cfe4a5e3f19abccd0ff786f654b9a04d2f)) * **store:** add custom labels for links ([#1183](https://www.github.com/jef/streetmerchant/issues/1183)) ([f7b32e8](https://www.github.com/jef/streetmerchant/commit/f7b32e8ac56c29207c6b30b9168c34c021a5e227)), closes [#1132](https://www.github.com/jef/streetmerchant/issues/1132) [#1163](https://www.github.com/jef/streetmerchant/issues/1163)
* **store:** add microcenter store location config ([#215](https://www.github.com/jef/nvidia-snatcher/issues/215)) ([d6a27c9](https://www.github.com/jef/nvidia-snatcher/commit/d6a27c988c7b1011c7a10084d8283a60ed8aea5c)) * **store:** add el corte ingles ([#1107](https://www.github.com/jef/streetmerchant/issues/1107)) ([75ee95b](https://www.github.com/jef/streetmerchant/commit/75ee95b2217fb4bf667869011a009210ff8c22e7))
* **stores:** add 3090 for bestbuy, newegg ([#249](https://www.github.com/jef/nvidia-snatcher/issues/249)) ([dd45dba](https://www.github.com/jef/nvidia-snatcher/commit/dd45dba82cb86f7e7664298dd202b93bbbd46d9f)) * **store:** add ePrice store ([#1016](https://www.github.com/jef/streetmerchant/issues/1016)) ([30a51a3](https://www.github.com/jef/streetmerchant/commit/30a51a38bee1c399276466e5db457bbe702edd5c))
* **stores:** add 3090s for amazon-ca, bestbuy-ca, newegg-ca ([#258](https://www.github.com/jef/nvidia-snatcher/issues/258)) ([482fb58](https://www.github.com/jef/nvidia-snatcher/commit/482fb58cbfde6f95fb6f77de790d76e6aa2a5926)) * **store:** add Euronics DE ([#1045](https://www.github.com/jef/streetmerchant/issues/1045)) ([1774afc](https://www.github.com/jef/streetmerchant/commit/1774afc1c3010bd0b183907baa4f3486dc9e8c23))
* add chromium sandbox skipping ([#209](https://www.github.com/jef/nvidia-snatcher/issues/209)) ([2065680](https://www.github.com/jef/nvidia-snatcher/commit/20656805c1259637bb3a4db465a8d16d4780296a)) * **store:** add expert ([#1105](https://www.github.com/jef/streetmerchant/issues/1105)) ([202698f](https://www.github.com/jef/streetmerchant/commit/202698f9179b081bd4214979f054e5ff7c805621))
* deprecate nvidia (api), add 3080 add 3090 ([9f470f0](https://www.github.com/jef/nvidia-snatcher/commit/9f470f06e9e9fb605d340c0b0f9016d7288e8c0b)) * **store:** add Gamestop DE ([#1046](https://www.github.com/jef/streetmerchant/issues/1046)) ([79a3f33](https://www.github.com/jef/streetmerchant/commit/79a3f33150188c7ff0228a38f276ae1fe88b9714))
* invert logic ([#141](https://www.github.com/jef/nvidia-snatcher/issues/141)) ([6608a79](https://www.github.com/jef/nvidia-snatcher/commit/6608a79769ff03543ab4ed2f2cead3410d7d7e99)) * **store:** add Medimax ([#1057](https://www.github.com/jef/streetmerchant/issues/1057)) ([7d29ef8](https://www.github.com/jef/streetmerchant/commit/7d29ef80ba1ae6682b486ac0b65a516b15a19f93))
* multiple discord roles and webhooks, qol for envs ([#260](https://www.github.com/jef/nvidia-snatcher/issues/260)) ([8913879](https://www.github.com/jef/nvidia-snatcher/commit/8913879593252c9c83020b2e2c46bad7537b2a20)) * **store:** add Otto ([#1096](https://www.github.com/jef/streetmerchant/issues/1096)) ([af96c5f](https://www.github.com/jef/streetmerchant/commit/af96c5f2e808af7496f3c3299e4cf173105de48b))
* **store:** add newegg.ca ([#160](https://www.github.com/jef/nvidia-snatcher/issues/160)) ([76f5849](https://www.github.com/jef/nvidia-snatcher/commit/76f584988979a40269fd3641e996800a63b4b163)), closes [#159](https://www.github.com/jef/nvidia-snatcher/issues/159) * **store:** add smythstoys ([1ed0593](https://www.github.com/jef/streetmerchant/commit/1ed05937676c3b6961fcbbb1f3aa80afc3411ac3))
* **store:** add office depot ([#157](https://www.github.com/jef/nvidia-snatcher/issues/157)) ([0df2dcf](https://www.github.com/jef/nvidia-snatcher/commit/0df2dcfbd48235fba7126d96cd912634c5b4fdd9)) * **store:** add some italian stores with ps5 links ([#976](https://www.github.com/jef/streetmerchant/issues/976)) ([f663579](https://www.github.com/jef/streetmerchant/commit/f663579f3d744a5270878975407ad30b31ee0c0a))
* **store:** add zotac store ([#214](https://www.github.com/jef/nvidia-snatcher/issues/214)) ([7875855](https://www.github.com/jef/nvidia-snatcher/commit/78758552b22e608dbdf3e76397f5b5efb893fef5)) * **store:** add spielegrotte ([#1056](https://www.github.com/jef/streetmerchant/issues/1056)) ([cf70f1f](https://www.github.com/jef/streetmerchant/commit/cf70f1ff4f942922bfa52adcd5b905e0b39c812a))
* add delay on captcha to try and evade faster ([#119](https://www.github.com/jef/nvidia-snatcher/issues/119)) ([4f83b3b](https://www.github.com/jef/nvidia-snatcher/commit/4f83b3b233657841a4068a8ff9dd6c8dbff631c0)) * **store:** add wipoid store ([#1018](https://www.github.com/jef/streetmerchant/issues/1018)) ([feae978](https://www.github.com/jef/streetmerchant/commit/feae978de9e90b96f542d2e53807144d82e380a4))
* bestbuy bypass international splash, newegg add to cart ([#153](https://www.github.com/jef/nvidia-snatcher/issues/153)) ([133a54f](https://www.github.com/jef/nvidia-snatcher/commit/133a54fa170bb16dd26b0d72b1a02c56b3851b7f)) * **store:** update the italian store links ([#1002](https://www.github.com/jef/streetmerchant/issues/1002)) ([de7036c](https://www.github.com/jef/streetmerchant/commit/de7036c7cc6dd7e436ad1d31b988d9d56ad31f76))
* card series filter, fix: newegg `oosLabels` ([#120](https://www.github.com/jef/nvidia-snatcher/issues/120)) ([252459d](https://www.github.com/jef/nvidia-snatcher/commit/252459d5d3de2b8cb25deee9ae318108e3dda2be)) * **topachat:** add `maxPrice` ([d7f2427](https://www.github.com/jef/streetmerchant/commit/d7f242780ef1a0a06d5b65ccfc0999e36a87d49d)), closes [#1097](https://www.github.com/jef/streetmerchant/issues/1097)
* custom user agent ([#121](https://www.github.com/jef/nvidia-snatcher/issues/121)) ([d9be3fe](https://www.github.com/jef/nvidia-snatcher/commit/d9be3fe6183eaa9694b186c7a75e1f28bb31dace)) * add proxy rotation (settable per store) ([#1026](https://www.github.com/jef/streetmerchant/issues/1026)) ([490d44e](https://www.github.com/jef/streetmerchant/commit/490d44e1fdfdf91db7344dd3050ba8fd8d069631))
* include screenshot for emails + sms notifications ([#144](https://www.github.com/jef/nvidia-snatcher/issues/144)) ([7191e03](https://www.github.com/jef/nvidia-snatcher/commit/7191e03a80e577b59b2861289aa658cfa0ffc0fa))
* load puppeteer faster, run stores in parallel ([#83](https://www.github.com/jef/nvidia-snatcher/issues/83)) ([d1a5aa1](https://www.github.com/jef/nvidia-snatcher/commit/d1a5aa1f02ff0a8f293b93e3c078b5943908a95b))
* set country in config, login to nvidia when starting ([#162](https://www.github.com/jef/nvidia-snatcher/issues/162)) ([ebd6091](https://www.github.com/jef/nvidia-snatcher/commit/ebd6091a09fb5e52a66742767ae4b58323cd7447))
* temporarily pause requests if store has stock ([#147](https://www.github.com/jef/nvidia-snatcher/issues/147)) ([6413144](https://www.github.com/jef/nvidia-snatcher/commit/6413144c1cae89f33f852cc93870b407a784f2bb))
* update for complex add to cart, fix nvidia ([#108](https://www.github.com/jef/nvidia-snatcher/issues/108)) ([3ea146d](https://www.github.com/jef/nvidia-snatcher/commit/3ea146da14ea40d145ccfc05436beeb0a9fed8d9))
* **notification:** discord integration ([#82](https://www.github.com/jef/nvidia-snatcher/issues/82)) ([a3fc07d](https://www.github.com/jef/nvidia-snatcher/commit/a3fc07daf0a3f33f18e03d4cfc13d3477a9c4fa0))
* **scraping:** change lookup impl, add randomize sleep ([#110](https://www.github.com/jef/nvidia-snatcher/issues/110)) ([dc0f710](https://www.github.com/jef/nvidia-snatcher/commit/dc0f7106749b0afa0ff1c91cabb90b65be30e909))
* **store:** add adorama ([#104](https://www.github.com/jef/nvidia-snatcher/issues/104)) ([5b91065](https://www.github.com/jef/nvidia-snatcher/commit/5b910650430ad4806b22722efa9a013e72ea47e7))
* **store:** add asus ([#102](https://www.github.com/jef/nvidia-snatcher/issues/102)) ([a501cf7](https://www.github.com/jef/nvidia-snatcher/commit/a501cf703bb05f47af6240a4b16a3dc4dcf3baf5))
### Bug Fixes ### Bug Fixes
* **store:** adorama captcha config ([#234](https://www.github.com/jef/nvidia-snatcher/issues/234)) ([9a53917](https://www.github.com/jef/nvidia-snatcher/commit/9a539175860f98de3b023009f751e59d94f0aaef)) * **amazon:** price and cart buttons ([6fd023e](https://www.github.com/jef/streetmerchant/commit/6fd023e81e0c54e8fb53b45817b63cb49b8a37ce)), closes [#1125](https://www.github.com/jef/streetmerchant/issues/1125)
* color logs and notification ([76b28a6](https://www.github.com/jef/nvidia-snatcher/commit/76b28a6dbdf5480c12a8c82b031c3f2880d17b11)) * **amazon-de:** `inStock` selector ([14cbd5a](https://www.github.com/jef/streetmerchant/commit/14cbd5a05b6f9c3a3ebbc5978156ff2b090efd32)), closes [#1178](https://www.github.com/jef/streetmerchant/issues/1178)
* **notification:** change discord ping visibility ([#168](https://www.github.com/jef/nvidia-snatcher/issues/168)) ([9675c5b](https://www.github.com/jef/nvidia-snatcher/commit/9675c5b8d61226db4652964e7f1e7399bb82d04e)) * **amazon-de:** remove xbox cart links ([cbc4330](https://www.github.com/jef/streetmerchant/commit/cbc43304bf49863000f422fbff4ed200ea610914)), closes [#1095](https://www.github.com/jef/streetmerchant/issues/1095)
* **store:** bandh removed cards ([#201](https://www.github.com/jef/nvidia-snatcher/issues/201)) ([6409646](https://www.github.com/jef/nvidia-snatcher/commit/6409646d57bf2b2bb5a4bcf8239740abed8edafb)) * **bestbuy-ca:** model always indicating in stock ([#1145](https://www.github.com/jef/streetmerchant/issues/1145)) ([06f3aaf](https://www.github.com/jef/streetmerchant/commit/06f3aafae6ec460c6227a92e6105639be71fc9b3))
* `rateLimitTimeout` not being defaulted ([#106](https://www.github.com/jef/nvidia-snatcher/issues/106)) ([28947be](https://www.github.com/jef/nvidia-snatcher/commit/28947be9bc8981d7a45a5d0e69c18d039fcd9ed3)) * **bestbuy-ca:** replace old evga xc3 ultra ([#1058](https://www.github.com/jef/streetmerchant/issues/1058)) ([65df944](https://www.github.com/jef/streetmerchant/commit/65df9449730bce2acb82f5edac25a91bdddd94db))
* check response for rate limiting ([#58](https://www.github.com/jef/nvidia-snatcher/issues/58)) ([#98](https://www.github.com/jef/nvidia-snatcher/issues/98)) ([b7d9462](https://www.github.com/jef/nvidia-snatcher/commit/b7d9462e794ef3961fb57c79ef8f66e77d25d20a)) * **canadacomputers:** add `inStock` selector, use english links ([#889](https://www.github.com/jef/streetmerchant/issues/889)) ([06214eb](https://www.github.com/jef/streetmerchant/commit/06214eb4a8a5c2d8a180e8dcf846f828d5cce2ed))
* keep single `Store` from draining ([e819e46](https://www.github.com/jef/nvidia-snatcher/commit/e819e46116d4e0b067a59791094b5cfbd2d7cd45)) * **memoryexpress:** add backorder to `outOfStock` selector ([#890](https://www.github.com/jef/streetmerchant/issues/890)) ([67605a6](https://www.github.com/jef/streetmerchant/commit/67605a6e280af35f210c536bc03571a84ea1a7e9))
* memory leak due to adblocker ([#139](https://www.github.com/jef/nvidia-snatcher/issues/139)) ([0f6e570](https://www.github.com/jef/nvidia-snatcher/commit/0f6e570cc817dfc10bcddc5743a0faf3b1489270)) * **newegg:** maxPrice selector using used price ([feddac7](https://www.github.com/jef/streetmerchant/commit/feddac76d3824e947b0a96524cd940e6b45ffe70)), closes [#1052](https://www.github.com/jef/streetmerchant/issues/1052)
* **nvidia:** false positives ([#132](https://www.github.com/jef/nvidia-snatcher/issues/132)) ([a75d214](https://www.github.com/jef/nvidia-snatcher/commit/a75d214dd555d5e0388cb54b15be324cc25b6a15)) * **newegg:** typo in 5800x url([#903](https://www.github.com/jef/streetmerchant/issues/903)) ([a99eecb](https://www.github.com/jef/streetmerchant/commit/a99eecb4613bc136e65afe4e5e8788316beae39e))
* newegg out-of-stock ([#124](https://www.github.com/jef/nvidia-snatcher/issues/124)) ([770a13a](https://www.github.com/jef/nvidia-snatcher/commit/770a13ac3559401b430547908d1df014582c1e37)) * **scan:** links builder ([#1161](https://www.github.com/jef/streetmerchant/issues/1161)) ([ca5553c](https://www.github.com/jef/streetmerchant/commit/ca5553cb2044c00857412a2af009e5e7f2c1aabf))
* newegg out-of-stock labels ([#134](https://www.github.com/jef/nvidia-snatcher/issues/134)) ([19c8f18](https://www.github.com/jef/nvidia-snatcher/commit/19c8f188c796258c469c2b4c6461fc5da3907a47)) * **smythstoys:** add out of stock label ([5bbdfa2](https://www.github.com/jef/streetmerchant/commit/5bbdfa2abc23c2e1fb1c606227754a1701cab194))
* **notification:** wrong condition for sounds playing ([#91](https://www.github.com/jef/nvidia-snatcher/issues/91)) ([103d96d](https://www.github.com/jef/nvidia-snatcher/commit/103d96dc81d6fd097fcdbed5bdd7487d7d73bf6e)) * **store:** add backoffStatusCodes and new captcha container ([#1110](https://www.github.com/jef/streetmerchant/issues/1110)) ([0b11238](https://www.github.com/jef/streetmerchant/commit/0b11238370040e9cd31e793e9a782ad384c22abf))
* **store:** false positives for nvidia. ([#85](https://www.github.com/jef/nvidia-snatcher/issues/85)) ([c65fa04](https://www.github.com/jef/nvidia-snatcher/commit/c65fa04666775060532e28076a0b4af50f8dd30b)) * **store:** removes unnecessary newegg links from bestbuy ([#1126](https://www.github.com/jef/streetmerchant/issues/1126)) ([f2ae423](https://www.github.com/jef/streetmerchant/commit/f2ae423fa83d1671a98b9cf3733e587d33727a59)), closes [#1119](https://www.github.com/jef/streetmerchant/issues/1119)
* **store:** update euroFormat for expert and otto ([#1108](https://www.github.com/jef/streetmerchant/issues/1108)) ([e198e44](https://www.github.com/jef/streetmerchant/commit/e198e44613cda27c0e67dc7e42ca514e66e9cf48))
* **walmart:** instock container and add test:series ([21e74cf](https://www.github.com/jef/streetmerchant/commit/21e74cfe76a5ccf82247315c9951a25e44bb1ce5)), closes [#1106](https://www.github.com/jef/streetmerchant/issues/1106)
* related products being picked up on scan ([#954](https://www.github.com/jef/streetmerchant/issues/954)) ([db18157](https://www.github.com/jef/streetmerchant/commit/db18157a490b9c9672c32de3372bff0b472a48f3))
## [1.4.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.3.0...v1.4.0) (2020-09-19) ## [3.1.0](https://www.github.com/jef/streetmerchant/compare/v3.0.0...v3.1.0) (2020-11-22)
### Features ### Features
* **notification:** add mint mobile carrier ([#70](https://www.github.com/jef/nvidia-snatcher/issues/70)) ([8aba7ec](https://www.github.com/jef/nvidia-snatcher/commit/8aba7ecbdb0bfce06257b7b9066e8fccbd82e47e)) * **asus:** add backoff codes ([#790](https://www.github.com/jef/streetmerchant/issues/790)) ([501ea34](https://www.github.com/jef/streetmerchant/commit/501ea34a54e877600050d5a99fd3b71ec799e96a))
* **notification:** add pushover ([#55](https://www.github.com/jef/nvidia-snatcher/issues/55)) ([c85658b](https://www.github.com/jef/nvidia-snatcher/commit/c85658bf82fdf360e5e9d8345eaa846f0572e67c)) * **canadacomputers:** add ryzen 5000 series ([#842](https://www.github.com/jef/streetmerchant/issues/842)) ([6f27330](https://www.github.com/jef/streetmerchant/commit/6f273305df69ac7b420b5446b4c6824866821a7e))
* **notification:** add telegram ([#71](https://www.github.com/jef/nvidia-snatcher/issues/71)) ([393d5f6](https://www.github.com/jef/nvidia-snatcher/commit/393d5f689887bf1d6f30a37eea163b2e6bbd4efa)) * **coolmod:** add `maxPrice` ([#862](https://www.github.com/jef/streetmerchant/issues/862)) ([4b689cb](https://www.github.com/jef/streetmerchant/commit/4b689cb94e99b83c8829c11d1bfe4cd6db9fbd7a))
* **notification:** add telus sms ([6be74a1](https://www.github.com/jef/nvidia-snatcher/commit/6be74a19f3d3f999145d17ac8e91c59db2502071)) * **newegg-ca:** add big navi links ([#843](https://www.github.com/jef/streetmerchant/issues/843)) ([6d292a1](https://www.github.com/jef/streetmerchant/commit/6d292a11cd53bd3893d4a0ff5d13eb2ce3319faa))
* **store:** add amazon.ca, fix timeout ([#75](https://www.github.com/jef/nvidia-snatcher/issues/75)) ([d4de1a4](https://www.github.com/jef/nvidia-snatcher/commit/d4de1a4638e903eb9518354ab6fb2f8c4befc347)) * **notification:** add product link to email and telegram ([#816](https://www.github.com/jef/streetmerchant/issues/816)) ([777c31b](https://www.github.com/jef/streetmerchant/commit/777c31b420a38cab860d98bc6bd8b7ba990c55e7))
* webpage toggle, sound notification, fix evga links ([#52](https://www.github.com/jef/nvidia-snatcher/issues/52)) ([a217409](https://www.github.com/jef/nvidia-snatcher/commit/a21740942bbbbe967948062fa06cfc82c31eb755)) * **playstation:** add `outOfStock` label ([#812](https://www.github.com/jef/streetmerchant/issues/812)) ([eb314af](https://www.github.com/jef/streetmerchant/commit/eb314afda557369dd27266429ac991c47ecc6375))
* **store:** add `PlayStation` store ([#806](https://www.github.com/jef/streetmerchant/issues/806)) ([7c28c7f](https://www.github.com/jef/streetmerchant/commit/7c28c7f72b171ce914aba770d88e8b1213c41233))
* **store:** add 3070 models to pccomponentes & coolmod ([#820](https://www.github.com/jef/streetmerchant/issues/820)) ([d0ebffd](https://www.github.com/jef/streetmerchant/commit/d0ebffd056dc166e3557ccf694379bf8c10148b5))
* **store:** add amd rx 6000 series model ([#832](https://www.github.com/jef/streetmerchant/issues/832)) ([89a762e](https://www.github.com/jef/streetmerchant/commit/89a762e2f5cd2ebd56c2586b1ebead4171b67153))
* **store:** add captcha check to saturn and mediamarkt ([#876](https://www.github.com/jef/streetmerchant/issues/876)) ([2d01cfd](https://www.github.com/jef/streetmerchant/commit/2d01cfddff557f112c6d53473dad25eb299f2fc0))
* **store:** add corsair sfx PSUs ([#881](https://www.github.com/jef/streetmerchant/issues/881)) ([e552c91](https://www.github.com/jef/streetmerchant/commit/e552c9102dd9801dcfc35652f2aaa0b1eea18ebb))
* **store:** add topachat ([#776](https://www.github.com/jef/streetmerchant/issues/776)) ([c38bebb](https://www.github.com/jef/streetmerchant/commit/c38bebb49dbe8243d0e3f1205150a33f9ce745aa))
* **store:** add vsgamers ([#767](https://www.github.com/jef/streetmerchant/issues/767)) ([53739e0](https://www.github.com/jef/streetmerchant/commit/53739e05abf50bbaddb8079087339c9f353096c8))
* add amazon-fr to stores. ([#766](https://www.github.com/jef/streetmerchant/issues/766)) ([02d7c47](https://www.github.com/jef/streetmerchant/commit/02d7c47c4093ad71dfab31f93a9b1390f4cad8a0))
* **store:** support for canadacomputers ([#772](https://www.github.com/jef/streetmerchant/issues/772)) ([bd69e47](https://www.github.com/jef/streetmerchant/commit/bd69e471f7b47e7faf1d9858992d4157145518aa))
### Bug Fixes
* **amazon:** add 5800x and 5600x ([#802](https://www.github.com/jef/streetmerchant/issues/802)) ([167713b](https://www.github.com/jef/streetmerchant/commit/167713bb14080e5e1d2f77c7ee933918b6fd5cfc))
* **bestbuy-ca:** use proper selector ([#801](https://www.github.com/jef/streetmerchant/issues/801)) ([63d550c](https://www.github.com/jef/streetmerchant/commit/63d550ca63b9bfd534f37b7747a1fae057abedb4))
* **config:** correcting newline split for multiple user agents ([#824](https://www.github.com/jef/streetmerchant/issues/824)) ([f16a9fb](https://www.github.com/jef/streetmerchant/commit/f16a9fb331fd38590325f399bde369ffa17dbe10))
* **store:** generate links only for selected stores ([292e360](https://www.github.com/jef/streetmerchant/commit/292e3603fd527a4454639c9abb73bd80a8a95fae)), closes [#694](https://www.github.com/jef/streetmerchant/issues/694)
### Reverts
* correcting newline split for multiple user agents ([af631c8](https://www.github.com/jef/streetmerchant/commit/af631c86f1a74d810cabf2d0de1b7bb31d350095)), closes [#824](https://www.github.com/jef/streetmerchant/issues/824)
* pipeline changes ([efe0d64](https://www.github.com/jef/streetmerchant/commit/efe0d64f060e812fd9846073a13837a3f2a27862))
## [3.0.0](https://www.github.com/jef/streetmerchant/compare/v2.0.0...v3.0.0) (2020-11-12)
### ⚠ BREAKING CHANGES
* removed duplicated `Model`
### Features
* **amazon:** add more 3070s ([#719](https://www.github.com/jef/streetmerchant/issues/719)) ([dde9837](https://www.github.com/jef/streetmerchant/commit/dde9837829b9d52e43800a2ac826b5dd00f5a744))
* **coolmod:** add zen 3 ([#754](https://www.github.com/jef/streetmerchant/issues/754)) ([3270292](https://www.github.com/jef/streetmerchant/commit/32702929a97236d7dc51aa8f669140bc6d89aa9a))
* **discord:** add cart link to embed ([#762](https://www.github.com/jef/streetmerchant/issues/762)) ([ccb207a](https://www.github.com/jef/streetmerchant/commit/ccb207abeb43b8e85f32c5c0a7a02aa33b5cdd7c))
* **store:** support for kabum (amd and rtx 30 series) ([#727](https://www.github.com/jef/streetmerchant/issues/727)) ([23d061b](https://www.github.com/jef/streetmerchant/commit/23d061b387b540803a81212fee937d4c8c9b17ad))
* add option to disable auto add to cart ([#759](https://www.github.com/jef/streetmerchant/issues/759)) ([a5249ec](https://www.github.com/jef/streetmerchant/commit/a5249ecc7c3acc29a1f9d5285bd77397263cb135))
* fix metadata in logging, lint prettier, typed `Model`s ([#747](https://www.github.com/jef/streetmerchant/issues/747)) ([318e626](https://www.github.com/jef/streetmerchant/commit/318e626e78c18524c4d8624176ccb659c6b6d17c))
* **amazon-ca:** add ps5 ([#713](https://www.github.com/jef/streetmerchant/issues/713)) ([2570056](https://www.github.com/jef/streetmerchant/commit/25700567c57a303a9376351daf015741193350a3))
* **amd:** add 5950 config ([#685](https://www.github.com/jef/streetmerchant/issues/685)) ([31a3d8f](https://www.github.com/jef/streetmerchant/commit/31a3d8f7e068a17c72e0c296e176b93625bf9063))
* **amd:** add env vars and series filtering ([#696](https://www.github.com/jef/streetmerchant/issues/696)) ([df3b10b](https://www.github.com/jef/streetmerchant/commit/df3b10b9a5c2467e00cacb3ab93f818aafc95f02))
* **galaxus:** add zen 3 ([#729](https://www.github.com/jef/streetmerchant/issues/729)) ([4e086e9](https://www.github.com/jef/streetmerchant/commit/4e086e92675df97fe7f94c4e6d51b73d63e7effb))
* **mindfactory:** add ryzen 5900x, 5950x ([#720](https://www.github.com/jef/streetmerchant/issues/720)) ([0362bf8](https://www.github.com/jef/streetmerchant/commit/0362bf808198d47e6aaa4a4838251f870d6dce4a))
* **notification:** add philips hue ([#681](https://www.github.com/jef/streetmerchant/issues/681)) ([c8a9b0b](https://www.github.com/jef/streetmerchant/commit/c8a9b0ba3ed581a9fef7ee2b459b1de84d976ff0))
* **notification:** support for multiple phone numbers ([#738](https://www.github.com/jef/streetmerchant/issues/738)) ([9f28fe5](https://www.github.com/jef/streetmerchant/commit/9f28fe5803fc71bf64d303cd1e7d20d0be8fecac))
* **ps5:** add console and digital edition ([#709](https://www.github.com/jef/streetmerchant/issues/709)) ([42ef7cf](https://www.github.com/jef/streetmerchant/commit/42ef7cfdced8ae3bc4192e245469798324bc42d3))
* **store:** add `arlt` and `amd-de` ([#721](https://www.github.com/jef/streetmerchant/issues/721)) ([38937f6](https://www.github.com/jef/streetmerchant/commit/38937f6880fcffb3a56ef17acd278f7c2f8d251c))
* **store:** add `game` store, add ps5 for uk stores ([#736](https://www.github.com/jef/streetmerchant/issues/736)) ([0128718](https://www.github.com/jef/streetmerchant/commit/0128718ba76b0c431d790cea7dd2183d10a02278))
* **store:** add ps5 to german stores ([#715](https://www.github.com/jef/streetmerchant/issues/715)) ([2291b8e](https://www.github.com/jef/streetmerchant/commit/2291b8eff5b23613d1233cc4c3ead83a42286d85))
* **store:** add xbox series x and s ([#732](https://www.github.com/jef/streetmerchant/issues/732)) ([314f533](https://www.github.com/jef/streetmerchant/commit/314f533f0bab0a466a276c5895d2f00bf86741f4))
* **store:** add zen 3 to german stores ([#702](https://www.github.com/jef/streetmerchant/issues/702)) ([71d5cb4](https://www.github.com/jef/streetmerchant/commit/71d5cb426179f5e587adeba1ec60f9a9233ec7b6))
* **store:** add zen 3 to more stores ([#698](https://www.github.com/jef/streetmerchant/issues/698)) ([760ddf5](https://www.github.com/jef/streetmerchant/commit/760ddf5d8523e28e294146643dda16e105176dff))
* **store:** Adds AM3 to microcenter ([#707](https://www.github.com/jef/streetmerchant/issues/707)) ([8a45905](https://www.github.com/jef/streetmerchant/commit/8a459056c5ba8a5a90de55cfbb08c4c89ccb19d3))
* **target:** add additional selector for 'ship it' ([#737](https://www.github.com/jef/streetmerchant/issues/737)) ([ab1fddf](https://www.github.com/jef/streetmerchant/commit/ab1fddf20c3a735b746befda0e21462701882645))
* add production scripts and better `Dockerfile` ([0d14500](https://www.github.com/jef/streetmerchant/commit/0d14500d5d8b93204bb99baf34dc9de745ae645d)), closes [#710](https://www.github.com/jef/streetmerchant/issues/710)
* bring back ascii banner, but make it configurable ([#703](https://www.github.com/jef/streetmerchant/issues/703)) ([0a680e9](https://www.github.com/jef/streetmerchant/commit/0a680e977b7904e7f62a8c1c0f3d533329b23fb0))
* memoryexpress website support ([#717](https://www.github.com/jef/streetmerchant/issues/717)) ([c02241c](https://www.github.com/jef/streetmerchant/commit/c02241c7528656c2c2fba9befc36628b4db7befb))
### Bug Fixes
* **docker:** copy web directory ([#745](https://www.github.com/jef/streetmerchant/issues/745)) ([0754fec](https://www.github.com/jef/streetmerchant/commit/0754feccaea2ce2dd37e7caeed3fa0b53c0cdcb3))
* **walmart:** ps5 digital url ([#763](https://www.github.com/jef/streetmerchant/issues/763)) ([841647c](https://www.github.com/jef/streetmerchant/commit/841647c06c488cf6b9d6d6af3c3eb6c8dbadab7e))
* environment variables to match ryzen cpus ([5db8348](https://www.github.com/jef/streetmerchant/commit/5db83484f301d48509205d9d0b5146c5d7114d26))
* revert to 14.15.0 until 15 is stable for `tsc` ([2955ea7](https://www.github.com/jef/streetmerchant/commit/2955ea70ab59c1b0dd82ec506c7a03952f81ea01)), closes [#691](https://www.github.com/jef/streetmerchant/issues/691)
### Code Refactoring
* removed duplicated `Model` ([d19dd5a](https://www.github.com/jef/streetmerchant/commit/d19dd5a404f2a585dd80f4d23d0e3af2d435ae85))
## [2.0.0](https://www.github.com/jef/streetmerchant/compare/v1.7.0...v2.0.0) (2020-11-05)
### ⚠ BREAKING CHANGES
* update naming to `streetmerchant`
### Features
* **asus:** realtime api ([#675](https://www.github.com/jef/streetmerchant/issues/675)) ([018784e](https://www.github.com/jef/streetmerchant/commit/018784e653831103465e8278db4929e04c52397c))
* **newegg-ca:** realtime api ([#674](https://www.github.com/jef/streetmerchant/issues/674)) ([3c5407f](https://www.github.com/jef/streetmerchant/commit/3c5407f5cfc635ae989101131188e999faa01d3c))
### Bug Fixes
* **filterBrandsSeriesModels:** always loop all stores ([#680](https://www.github.com/jef/streetmerchant/issues/680)) ([6ced13e](https://www.github.com/jef/streetmerchant/commit/6ced13e993f7b30bbdda5dc7615e895bac3e4f77))
### Miscellaneous Chores
* update naming to `streetmerchant` ([3f9b3c6](https://www.github.com/jef/streetmerchant/commit/3f9b3c6017431074d59550a6cd61c80a8897a9ae))
## [1.7.0](https://www.github.com/jef/streetmerchant/compare/v1.6.0...v1.7.0) (2020-11-03)
### Features
* add deprecation notices ([601742c](https://www.github.com/jef/streetmerchant/commit/601742cf2c0b5ccf0131e4c4e904ad4037d80a8d))
* newegg realtime api ([#664](https://www.github.com/jef/streetmerchant/issues/664)) ([5b3e95a](https://www.github.com/jef/streetmerchant/commit/5b3e95acdf2f427a6098f15b9fbe65e88354a678))
### Bug Fixes
* **banner:** add version to docker image ([#649](https://www.github.com/jef/streetmerchant/issues/649)) ([1d2a33b](https://www.github.com/jef/streetmerchant/commit/1d2a33b1d765fece9d1c9bf7d548818d1f0c8d92))
## [1.6.0](https://www.github.com/jef/streetmerchant/compare/v1.5.0...v1.6.0) (2020-10-29)
### Features
* add series to Discord webhook ([#618](https://www.github.com/jef/streetmerchant/issues/618)) ([273d058](https://www.github.com/jef/streetmerchant/commit/273d05841451ed896f1d505bcd24f2230a143d3a))
* **api:** add rudimentary web control panel ([#183](https://www.github.com/jef/streetmerchant/issues/183)) ([373d1a9](https://www.github.com/jef/streetmerchant/commit/373d1a973865b14b5753517aa70eabf85b136d94))
* **store:** add founders editions to notebooksbilliger.de ([#593](https://www.github.com/jef/streetmerchant/issues/593)) ([2e5db7a](https://www.github.com/jef/streetmerchant/commit/2e5db7af04e6ce79660477d8deb6636ec2e7845e))
* **store:** add max price containers to multiple stores ([#579](https://www.github.com/jef/streetmerchant/issues/579)) ([f9c4c25](https://www.github.com/jef/streetmerchant/commit/f9c4c258748ffd3735f1e7385bde15b6112a1ca7))
* **store:** add new cards to german web shops ([#597](https://www.github.com/jef/streetmerchant/issues/597)) ([699de57](https://www.github.com/jef/streetmerchant/commit/699de573f6579b59ba2c65cc2bf4dd6ccba3c863))
* **store:** Add PCComponentes and Amazon-ES Stores. ([#558](https://www.github.com/jef/streetmerchant/issues/558)) ([062201f](https://www.github.com/jef/streetmerchant/commit/062201f092c7a271202f27e7297b8eb9d7269c02))
* **store:** support for azerty ([#557](https://www.github.com/jef/streetmerchant/issues/557)) ([58416e1](https://www.github.com/jef/streetmerchant/commit/58416e1994006cc2e4055937c675e0f9191f6339))
* **store:** support for coolmod ([#605](https://www.github.com/jef/streetmerchant/issues/605)) ([c1dda4f](https://www.github.com/jef/streetmerchant/commit/c1dda4f9871988fad43d79f3bfe65f7c7860b9f7))
* add `meta` to logger ([#437](https://www.github.com/jef/streetmerchant/issues/437)) ([ae6bc86](https://www.github.com/jef/streetmerchant/commit/ae6bc86bcb75c154a2a68adda324f34f18281700))
* add alternate.nl support ([#552](https://www.github.com/jef/streetmerchant/issues/552)) ([aca6523](https://www.github.com/jef/streetmerchant/commit/aca65233339ddbbcc1dbd06f9011d6d44c6650cf))
* add asus-de store and asus 3080 tuf/oc to amazon-de ([#436](https://www.github.com/jef/streetmerchant/issues/436)) ([b4d8733](https://www.github.com/jef/streetmerchant/commit/b4d8733d1823e2fa5d3a1b80d2d4218bfa737cd7))
* add caseking and proshop-de store ([#521](https://www.github.com/jef/streetmerchant/issues/521)) ([1aaa102](https://www.github.com/jef/streetmerchant/commit/1aaa102c06281b60da593d04ced01f8b20a37a3b))
* add coolblue store ([#482](https://www.github.com/jef/streetmerchant/issues/482)) ([5c61333](https://www.github.com/jef/streetmerchant/commit/5c61333df00c0c30f04e4aced01a498c5816ad58))
* add german stores ([#462](https://www.github.com/jef/streetmerchant/issues/462)) ([85a07dc](https://www.github.com/jef/streetmerchant/commit/85a07dc0dc6a8dfe2aba1d4ea3e4cde6ec083086))
* add incognito mode ([#534](https://www.github.com/jef/streetmerchant/issues/534)) ([2b6457e](https://www.github.com/jef/streetmerchant/commit/2b6457e8409658b843204fa0aeafb00d48f9e53e))
* add link series to error message for better context ([#265](https://www.github.com/jef/streetmerchant/issues/265)) ([332b4a8](https://www.github.com/jef/streetmerchant/commit/332b4a8246320e458729c0b58c310d290df12530))
* Add PagerDuty Integration ([#565](https://www.github.com/jef/streetmerchant/issues/565)) ([11ee0bf](https://www.github.com/jef/streetmerchant/commit/11ee0bf1a3e2d0d550d2731f9de9e178c382ea1f))
* add proshop-dk ([#524](https://www.github.com/jef/streetmerchant/issues/524)) ([dc2fcf5](https://www.github.com/jef/streetmerchant/commit/dc2fcf5ab4dba8be459bd5aa6a41e3e097205d45))
* add support for multiple browser user agents ([#547](https://www.github.com/jef/streetmerchant/issues/547)) ([10a81dc](https://www.github.com/jef/streetmerchant/commit/10a81dcbd54557652537cb641cbbd727d39e34e5))
* add uk stores ([#455](https://www.github.com/jef/streetmerchant/issues/455)) ([b9b6b55](https://www.github.com/jef/streetmerchant/commit/b9b6b55c29d11f48b683816e5b8c1cab127ed5fd))
* allow filtering per model by a specific series ([#595](https://www.github.com/jef/streetmerchant/issues/595)) ([a42418f](https://www.github.com/jef/streetmerchant/commit/a42418f814dcd91354c136288d4c6a24e03a168d))
* optional per store min and max page sleep time ([#576](https://www.github.com/jef/streetmerchant/issues/576)) ([503d76f](https://www.github.com/jef/streetmerchant/commit/503d76f3c7d01368fc978af4ab02924d3d036ac0))
* **notification:** add `to` field for email ([#327](https://www.github.com/jef/streetmerchant/issues/327)) ([8828dd1](https://www.github.com/jef/streetmerchant/commit/8828dd15cd08959cd434bd256e8eac474dd17c49))
* **store:** add ttl for `scan` ([#555](https://www.github.com/jef/streetmerchant/issues/555)) ([4847725](https://www.github.com/jef/streetmerchant/commit/4847725d3a54d2f4dd0c349ff0ad80eb4bc4e9e3))
* add rog strix oc to amazon-de ([#471](https://www.github.com/jef/streetmerchant/issues/471)) ([e5909c5](https://www.github.com/jef/streetmerchant/commit/e5909c532da1c8b731e9835bffd8f31b76550d4d))
* add support for specifying smtp server ([#458](https://www.github.com/jef/streetmerchant/issues/458)) ([160ae37](https://www.github.com/jef/streetmerchant/commit/160ae37d7bee4f0323cb939566d586f1300aece6))
* allow multiple microcenter locations ([#487](https://www.github.com/jef/streetmerchant/issues/487)) ([2b0eab6](https://www.github.com/jef/streetmerchant/commit/2b0eab656d81314ce7d05064662ec138407550c3))
* clear cookies and cache ([#515](https://www.github.com/jef/streetmerchant/issues/515)) ([1f89945](https://www.github.com/jef/streetmerchant/commit/1f89945c5746befb2131381a358efdf8ac530e0c)), closes [#417](https://www.github.com/jef/streetmerchant/issues/417)
* max price per series ([#451](https://www.github.com/jef/streetmerchant/issues/451)) ([8adc07a](https://www.github.com/jef/streetmerchant/commit/8adc07a03e411dd536bebfdc7270db4bbf8ddb34))
* mqtt alerts ([#538](https://www.github.com/jef/streetmerchant/issues/538)) ([68ff5bf](https://www.github.com/jef/streetmerchant/commit/68ff5bf836c63c8e14d02c06777e02e64a6a0f38))
* twitch chat notification, multiple telegram chat ids and german web shop overhaul ([#528](https://www.github.com/jef/streetmerchant/issues/528)) ([675f13a](https://www.github.com/jef/streetmerchant/commit/675f13abb892d1158c92c41e3d57049313a5e0b8))
* **docker:** add docker and publish images to ghcr ([#411](https://www.github.com/jef/streetmerchant/issues/411)) ([c857985](https://www.github.com/jef/streetmerchant/commit/c857985a6d3736287976caf5b173f19046306465))
* **notification:** add at&t prepaid carrier ([#425](https://www.github.com/jef/streetmerchant/issues/425)) ([eb9d082](https://www.github.com/jef/streetmerchant/commit/eb9d082d178a42e35789ba822cfae7b35c0413c1))
* **notification:** add pushover priority setting ([#186](https://www.github.com/jef/streetmerchant/issues/186)) ([f277172](https://www.github.com/jef/streetmerchant/commit/f2771721914a20619833df8ccb2ac44298687b4d))
* **notification:** add Twillio notification provider ([#344](https://www.github.com/jef/streetmerchant/issues/344)) ([f2f8d81](https://www.github.com/jef/streetmerchant/commit/f2f8d81498d1acfb9359f4a690962042ec20d166))
* **store:** add `pny` ([#295](https://www.github.com/jef/streetmerchant/issues/295)) ([f6760d3](https://www.github.com/jef/streetmerchant/commit/f6760d3c65d60eae9e4b1e0fdba34e814f446a4c))
* **store:** add 3090s to amazon-ca ([#274](https://www.github.com/jef/streetmerchant/issues/274)) ([e992cf4](https://www.github.com/jef/streetmerchant/commit/e992cf4db85f045fc8d03c9b93286fb72bad1061))
* **store:** add additional cards to all stores ([#286](https://www.github.com/jef/streetmerchant/issues/286)) ([d25a643](https://www.github.com/jef/streetmerchant/commit/d25a643425020fa3f7cd48972360ede17501afeb))
* **store:** add amazon cards and `cartUrl`s ([#284](https://www.github.com/jef/streetmerchant/issues/284)) ([d69189f](https://www.github.com/jef/streetmerchant/commit/d69189f12c893fb6d88b198d802ff8e36a69bc88))
* **store:** add asus strix oc to asus store ([#385](https://www.github.com/jef/streetmerchant/issues/385)) ([e55398e](https://www.github.com/jef/streetmerchant/commit/e55398e789d52def6e15d1e5e10f56cdf5ea5bea))
* **store:** add evga 3090 to newegg canada ([#396](https://www.github.com/jef/streetmerchant/issues/396)) ([313d176](https://www.github.com/jef/streetmerchant/commit/313d176848a25f183334db8926ac0ec445a2c481))
* **store:** add ftw3 ultra to microcenter ([#448](https://www.github.com/jef/streetmerchant/issues/448)) ([5109227](https://www.github.com/jef/streetmerchant/commit/5109227e8899f57b828b157309a76c397c872559))
* **store:** add gamestop ([#390](https://www.github.com/jef/streetmerchant/issues/390)) ([7148451](https://www.github.com/jef/streetmerchant/commit/7148451b66e97f4f7dcdcc86ce06ba8712211bd5))
* **store:** add models to bestbuy ([#421](https://www.github.com/jef/streetmerchant/issues/421)) ([4085136](https://www.github.com/jef/streetmerchant/commit/4085136269b00f6bc5c8414836de8310dfec4166))
* **store:** add rog-strix-3080 to newegg-ca ([#489](https://www.github.com/jef/streetmerchant/issues/489)) ([207bc41](https://www.github.com/jef/streetmerchant/commit/207bc411ed240cd9150e018b21e735ba08a4d134))
* add `norway` to `nvidia-api` ([#304](https://www.github.com/jef/streetmerchant/issues/304)) ([eda6c85](https://www.github.com/jef/streetmerchant/commit/eda6c85fc03a70c5933308e96c572a480bb6c8a0))
* configurable status code behaviours ([#340](https://www.github.com/jef/streetmerchant/issues/340)) ([3b7487e](https://www.github.com/jef/streetmerchant/commit/3b7487e97ac9d93344403f50153f2de6243b1f0d))
* enhanced lookup behaviour ([#270](https://www.github.com/jef/streetmerchant/issues/270)) ([b868d1a](https://www.github.com/jef/streetmerchant/commit/b868d1a4833a8ec5ac1c79481530d75cd0c4b01e))
* in stock wait time per link now ([c7a716f](https://www.github.com/jef/streetmerchant/commit/c7a716f981976a76afe61a4d985bd6fe4343595b))
* low bandwidth mode ([#294](https://www.github.com/jef/streetmerchant/issues/294)) ([0aa7ab5](https://www.github.com/jef/streetmerchant/commit/0aa7ab596c907ce72c188eb4b1acdee088307437))
* max price filtering ([#383](https://www.github.com/jef/streetmerchant/issues/383)) ([fd294d2](https://www.github.com/jef/streetmerchant/commit/fd294d2baa06a1c0a68852497889a0412dea492e))
* **store:** adds aorus master 3080 to newegg ([#402](https://www.github.com/jef/streetmerchant/issues/402)) ([fddc002](https://www.github.com/jef/streetmerchant/commit/fddc0021d36e4d0a9dacccc546da8260684f0eeb))
* retry logic for nvidia session token and adding to cart ([#347](https://www.github.com/jef/streetmerchant/issues/347)) ([1bac1b9](https://www.github.com/jef/streetmerchant/commit/1bac1b928d401a819698848f3367edf54836b26f))
* support for proxy server ([#352](https://www.github.com/jef/streetmerchant/issues/352)) ([fdcd787](https://www.github.com/jef/streetmerchant/commit/fdcd787f91f26229db23e2291e8922b947007902))
* **store:** nvidia debug card for "product details" page ([#337](https://www.github.com/jef/streetmerchant/issues/337)) ([5b8d774](https://www.github.com/jef/streetmerchant/commit/5b8d774b7c7d31d6ba6fc43be3ea7b16a87d2e49))
### Bug Fixes
* `amazon.{nl,de}` test urls ([#345](https://www.github.com/jef/streetmerchant/issues/345)) ([589fbbc](https://www.github.com/jef/streetmerchant/commit/589fbbcd34393ceb2bd7c0a8ac391c54e14a21be))
* `envOrNumber` behavior ([#364](https://www.github.com/jef/streetmerchant/issues/364)) ([7d8897c](https://www.github.com/jef/streetmerchant/commit/7d8897cd9fb9ae0db796fd85da3f2b9d1a9f73af))
* `nvidia-api` ([#314](https://www.github.com/jef/streetmerchant/issues/314)) ([8d8e5b5](https://www.github.com/jef/streetmerchant/commit/8d8e5b587d2279a95d3e7837a99bea8c5990a477))
* add `amazon-nl`, captcha `amazon-de`, add ftw3 `newegg` ([#293](https://www.github.com/jef/streetmerchant/issues/293)) ([a2983eb](https://www.github.com/jef/streetmerchant/commit/a2983eb54c419ba3a56abf80d316ea136a05e0fa))
* add status code `429` to bandh `backOffStatusCodes` ([#404](https://www.github.com/jef/streetmerchant/issues/404)) ([7a981e7](https://www.github.com/jef/streetmerchant/commit/7a981e745673f2b12d48d7eed71fc34a6e4ba5b2))
* add support for stores label text to have uppercase letters ([#526](https://www.github.com/jef/streetmerchant/issues/526)) ([5ea7cc4](https://www.github.com/jef/streetmerchant/commit/5ea7cc4ca45c506d2b98d4b643b44ca4ede1d7a9))
* asus store links ([#573](https://www.github.com/jef/streetmerchant/issues/573)) ([f6db348](https://www.github.com/jef/streetmerchant/commit/f6db3489b8b8a737dfc425880703928d5bc8916d))
* bestbuy label container selector precision ([#491](https://www.github.com/jef/streetmerchant/issues/491)) ([cbc3b0b](https://www.github.com/jef/streetmerchant/commit/cbc3b0b025469e9882ba8267f18f909c08c6c931))
* corrected norway locales ([#356](https://www.github.com/jef/streetmerchant/issues/356)) ([d2476dd](https://www.github.com/jef/streetmerchant/commit/d2476ddb08606545b32b9676e2d299d57ec5cb6a))
* cyclical dependencies ([ed970fc](https://www.github.com/jef/streetmerchant/commit/ed970fc397210eb6ff684c7e82c79eb685a5d0d9)), closes [#468](https://www.github.com/jef/streetmerchant/issues/468)
* denver `microcenter` name ([#296](https://www.github.com/jef/streetmerchant/issues/296)) ([349f55d](https://www.github.com/jef/streetmerchant/commit/349f55d3603517b5741fce6ac42b29141816ea79))
* dutch stores components ([#513](https://www.github.com/jef/streetmerchant/issues/513)) ([586029c](https://www.github.com/jef/streetmerchant/commit/586029c92aa19bdddcc85b7a837bb7a16bb1d28d))
* gamestop false positives ([#395](https://www.github.com/jef/streetmerchant/issues/395)) ([d3bb507](https://www.github.com/jef/streetmerchant/commit/d3bb507edca112124115ed88fb03cf14440d95ef))
* in stock wait time ([#325](https://www.github.com/jef/streetmerchant/issues/325)) ([07bd246](https://www.github.com/jef/streetmerchant/commit/07bd246e876cd27df1b5019af5ee8613bb5368f0)), closes [#315](https://www.github.com/jef/streetmerchant/issues/315)
* max price getter updated to match .env ([#516](https://www.github.com/jef/streetmerchant/issues/516)) ([32f114b](https://www.github.com/jef/streetmerchant/commit/32f114b23527ee247c84c081a2cd0264de3b4847)), closes [#514](https://www.github.com/jef/streetmerchant/issues/514) [#510](https://www.github.com/jef/streetmerchant/issues/510)
* page sleep ([#586](https://www.github.com/jef/streetmerchant/issues/586)) ([a2af30b](https://www.github.com/jef/streetmerchant/commit/a2af30b70334cdbbfa51140d5de23a2d6b8429c8)), closes [#594](https://www.github.com/jef/streetmerchant/issues/594) [#576](https://www.github.com/jef/streetmerchant/issues/576)
* remove 3090 drid for DK/FI regions ([#361](https://www.github.com/jef/streetmerchant/issues/361)) ([f1d22d1](https://www.github.com/jef/streetmerchant/commit/f1d22d1684c8e70f09acd9978e6ea802d7224c8b))
* trim strings from comma-separated values ([#472](https://www.github.com/jef/streetmerchant/issues/472)) ([f7ed865](https://www.github.com/jef/streetmerchant/commit/f7ed86506b4e76d5bc20787068be83a44ec485b5))
* typo in maxPrice for 3090 ([#496](https://www.github.com/jef/streetmerchant/issues/496)) ([e073590](https://www.github.com/jef/streetmerchant/commit/e0735903b7b4b0d542dbbd76b9a860b1eca24e96))
* update gigabyte model `vision oc` ([#550](https://www.github.com/jef/streetmerchant/issues/550)) ([4fefe22](https://www.github.com/jef/streetmerchant/commit/4fefe22a907094fa39af5b4f2e3f8f3fe6897115))
* update new additions with web panel and sleep operations ([#606](https://www.github.com/jef/streetmerchant/issues/606)) ([61a23fe](https://www.github.com/jef/streetmerchant/commit/61a23fe9782223dc067dbc8251c3b09adbca0a43))
* update pushbullet import to match package ([#637](https://www.github.com/jef/streetmerchant/issues/637)) ([d7360f7](https://www.github.com/jef/streetmerchant/commit/d7360f71ef1a076713246ad2832ca58e7163e492))
* **env:** default `LOG_LEVEL` ([9636572](https://www.github.com/jef/streetmerchant/commit/9636572c7de36f7ac6800ba31ac60fcd7bd2fd03))
* **notification:** discord false triggers ([#346](https://www.github.com/jef/streetmerchant/issues/346)) ([3b90bbb](https://www.github.com/jef/streetmerchant/commit/3b90bbbe5d751003a39823e9113eaee8cbfcf1a2))
* **notification:** sms subject output ([#298](https://www.github.com/jef/streetmerchant/issues/298)) ([03755d5](https://www.github.com/jef/streetmerchant/commit/03755d5eb117ac14797e0180c74f50b401e50cb5))
* **notifications:** twilio client creation ([#349](https://www.github.com/jef/streetmerchant/issues/349)) ([5414b24](https://www.github.com/jef/streetmerchant/commit/5414b249a6f938615cfad02ca22c171a5f86e127))
* **store:** gamestop `label.inStock` ([9e7976d](https://www.github.com/jef/streetmerchant/commit/9e7976df5778a953c4fb6ca7553773655c1f4127))
* **store:** pccomponents model normalization ([#563](https://www.github.com/jef/streetmerchant/issues/563)) ([699e77d](https://www.github.com/jef/streetmerchant/commit/699e77d960b17dcb50378975a1913b0badeabfcc))
* updating amazon test model card to an in stock product ([#492](https://www.github.com/jef/streetmerchant/issues/492)) ([81daa7c](https://www.github.com/jef/streetmerchant/commit/81daa7c5596ab23bd9e6aac29fa63ee09e136827))
* **config:** `MAX_PRICE` quotations ([#426](https://www.github.com/jef/streetmerchant/issues/426)) ([b7e5941](https://www.github.com/jef/streetmerchant/commit/b7e5941a9598a09afabbb79c5636b768345009a3))
* **store:** container names on `nvidia` ([#333](https://www.github.com/jef/streetmerchant/issues/333)) ([772de90](https://www.github.com/jef/streetmerchant/commit/772de900a1386e9635d139e152fe86366404ded4))
* **store:** update `inStock` and `maxPrice` for newegg, newegg-ca ([#433](https://www.github.com/jef/streetmerchant/issues/433)) ([628cab1](https://www.github.com/jef/streetmerchant/commit/628cab1b605e4363c8dd5ad43476292ecb12db74)), closes [#400](https://www.github.com/jef/streetmerchant/issues/400)
### Reverts
* reduce false-positive during ci/cd ([79b9bfe](https://www.github.com/jef/streetmerchant/commit/79b9bfe9a83858117f7a58b4b8b1a1569d80c442))
## [1.5.0](https://www.github.com/jef/streetmerchant/compare/v1.4.0...v1.5.0) (2020-09-24)
### Features
* filter models ([#261](https://www.github.com/jef/streetmerchant/issues/261)) ([e1b34a9](https://www.github.com/jef/streetmerchant/commit/e1b34a9ccfa45fa1a11da9af9074059b6084904b))
* **log:** colors for console logs ([#207](https://www.github.com/jef/streetmerchant/issues/207)) ([0ad67fe](https://www.github.com/jef/streetmerchant/commit/0ad67fe20453898ce0a6b5faff00062735411119))
* **notification:** add desktop notifications ([#140](https://www.github.com/jef/streetmerchant/issues/140)) ([722eaf3](https://www.github.com/jef/streetmerchant/commit/722eaf3cd680c4600b79f842c6c5acdb9e51ad71))
* **notification:** add pushbullet, add url with notifications ([#226](https://www.github.com/jef/streetmerchant/issues/226)) ([74490ea](https://www.github.com/jef/streetmerchant/commit/74490eae3ab30de7d7a708d5dd970e070f27f2ea))
* **notification:** twitter integration ([#224](https://www.github.com/jef/streetmerchant/issues/224)) ([908ed35](https://www.github.com/jef/streetmerchant/commit/908ed358826f9de530f5892ded1a54964a304d15))
* **store:** add `bannedSeller` label for stores ([#173](https://www.github.com/jef/streetmerchant/issues/173)) ([71c6774](https://www.github.com/jef/streetmerchant/commit/71c6774511f7ba13d34d2e40b69abf52d06e6225))
* **store:** add amazon-de ([#167](https://www.github.com/jef/streetmerchant/issues/167)) ([8a70f14](https://www.github.com/jef/streetmerchant/commit/8a70f147438584cc334710bc66220d05eb32fcbd))
* **store:** add bestbuy.ca ([#229](https://www.github.com/jef/streetmerchant/issues/229)) ([22fd22f](https://www.github.com/jef/streetmerchant/commit/22fd22fe743d3e286eae3430aecd6e7a0a5de8c0))
* **store:** add evga eu ([#172](https://www.github.com/jef/streetmerchant/issues/172)) ([605bdd7](https://www.github.com/jef/streetmerchant/commit/605bdd7ca73c585734f6c5df1a86f4fbfbff9163))
* **store:** add evga model ([#220](https://www.github.com/jef/streetmerchant/issues/220)) ([190388c](https://www.github.com/jef/streetmerchant/commit/190388cfe4a5e3f19abccd0ff786f654b9a04d2f))
* **store:** add microcenter store location config ([#215](https://www.github.com/jef/streetmerchant/issues/215)) ([d6a27c9](https://www.github.com/jef/streetmerchant/commit/d6a27c988c7b1011c7a10084d8283a60ed8aea5c))
* **stores:** add 3090 for bestbuy, newegg ([#249](https://www.github.com/jef/streetmerchant/issues/249)) ([dd45dba](https://www.github.com/jef/streetmerchant/commit/dd45dba82cb86f7e7664298dd202b93bbbd46d9f))
* **stores:** add 3090s for amazon-ca, bestbuy-ca, newegg-ca ([#258](https://www.github.com/jef/streetmerchant/issues/258)) ([482fb58](https://www.github.com/jef/streetmerchant/commit/482fb58cbfde6f95fb6f77de790d76e6aa2a5926))
* add chromium sandbox skipping ([#209](https://www.github.com/jef/streetmerchant/issues/209)) ([2065680](https://www.github.com/jef/streetmerchant/commit/20656805c1259637bb3a4db465a8d16d4780296a))
* deprecate nvidia (api), add 3080 add 3090 ([9f470f0](https://www.github.com/jef/streetmerchant/commit/9f470f06e9e9fb605d340c0b0f9016d7288e8c0b))
* invert logic ([#141](https://www.github.com/jef/streetmerchant/issues/141)) ([6608a79](https://www.github.com/jef/streetmerchant/commit/6608a79769ff03543ab4ed2f2cead3410d7d7e99))
* multiple discord roles and webhooks, qol for envs ([#260](https://www.github.com/jef/streetmerchant/issues/260)) ([8913879](https://www.github.com/jef/streetmerchant/commit/8913879593252c9c83020b2e2c46bad7537b2a20))
* **store:** add newegg.ca ([#160](https://www.github.com/jef/streetmerchant/issues/160)) ([76f5849](https://www.github.com/jef/streetmerchant/commit/76f584988979a40269fd3641e996800a63b4b163)), closes [#159](https://www.github.com/jef/streetmerchant/issues/159)
* **store:** add office depot ([#157](https://www.github.com/jef/streetmerchant/issues/157)) ([0df2dcf](https://www.github.com/jef/streetmerchant/commit/0df2dcfbd48235fba7126d96cd912634c5b4fdd9))
* **store:** add zotac store ([#214](https://www.github.com/jef/streetmerchant/issues/214)) ([7875855](https://www.github.com/jef/streetmerchant/commit/78758552b22e608dbdf3e76397f5b5efb893fef5))
* add delay on captcha to try and evade faster ([#119](https://www.github.com/jef/streetmerchant/issues/119)) ([4f83b3b](https://www.github.com/jef/streetmerchant/commit/4f83b3b233657841a4068a8ff9dd6c8dbff631c0))
* bestbuy bypass international splash, newegg add to cart ([#153](https://www.github.com/jef/streetmerchant/issues/153)) ([133a54f](https://www.github.com/jef/streetmerchant/commit/133a54fa170bb16dd26b0d72b1a02c56b3851b7f))
* card series filter, fix: newegg `oosLabels` ([#120](https://www.github.com/jef/streetmerchant/issues/120)) ([252459d](https://www.github.com/jef/streetmerchant/commit/252459d5d3de2b8cb25deee9ae318108e3dda2be))
* custom user agent ([#121](https://www.github.com/jef/streetmerchant/issues/121)) ([d9be3fe](https://www.github.com/jef/streetmerchant/commit/d9be3fe6183eaa9694b186c7a75e1f28bb31dace))
* include screenshot for emails + sms notifications ([#144](https://www.github.com/jef/streetmerchant/issues/144)) ([7191e03](https://www.github.com/jef/streetmerchant/commit/7191e03a80e577b59b2861289aa658cfa0ffc0fa))
* load puppeteer faster, run stores in parallel ([#83](https://www.github.com/jef/streetmerchant/issues/83)) ([d1a5aa1](https://www.github.com/jef/streetmerchant/commit/d1a5aa1f02ff0a8f293b93e3c078b5943908a95b))
* set country in config, login to nvidia when starting ([#162](https://www.github.com/jef/streetmerchant/issues/162)) ([ebd6091](https://www.github.com/jef/streetmerchant/commit/ebd6091a09fb5e52a66742767ae4b58323cd7447))
* temporarily pause requests if store has stock ([#147](https://www.github.com/jef/streetmerchant/issues/147)) ([6413144](https://www.github.com/jef/streetmerchant/commit/6413144c1cae89f33f852cc93870b407a784f2bb))
* update for complex add to cart, fix nvidia ([#108](https://www.github.com/jef/streetmerchant/issues/108)) ([3ea146d](https://www.github.com/jef/streetmerchant/commit/3ea146da14ea40d145ccfc05436beeb0a9fed8d9))
* **notification:** discord integration ([#82](https://www.github.com/jef/streetmerchant/issues/82)) ([a3fc07d](https://www.github.com/jef/streetmerchant/commit/a3fc07daf0a3f33f18e03d4cfc13d3477a9c4fa0))
* **scraping:** change lookup impl, add randomize sleep ([#110](https://www.github.com/jef/streetmerchant/issues/110)) ([dc0f710](https://www.github.com/jef/streetmerchant/commit/dc0f7106749b0afa0ff1c91cabb90b65be30e909))
* **store:** add adorama ([#104](https://www.github.com/jef/streetmerchant/issues/104)) ([5b91065](https://www.github.com/jef/streetmerchant/commit/5b910650430ad4806b22722efa9a013e72ea47e7))
* **store:** add asus ([#102](https://www.github.com/jef/streetmerchant/issues/102)) ([a501cf7](https://www.github.com/jef/streetmerchant/commit/a501cf703bb05f47af6240a4b16a3dc4dcf3baf5))
### Bug Fixes
* **store:** adorama captcha config ([#234](https://www.github.com/jef/streetmerchant/issues/234)) ([9a53917](https://www.github.com/jef/streetmerchant/commit/9a539175860f98de3b023009f751e59d94f0aaef))
* color logs and notification ([76b28a6](https://www.github.com/jef/streetmerchant/commit/76b28a6dbdf5480c12a8c82b031c3f2880d17b11))
* **notification:** change discord ping visibility ([#168](https://www.github.com/jef/streetmerchant/issues/168)) ([9675c5b](https://www.github.com/jef/streetmerchant/commit/9675c5b8d61226db4652964e7f1e7399bb82d04e))
* **store:** bandh removed cards ([#201](https://www.github.com/jef/streetmerchant/issues/201)) ([6409646](https://www.github.com/jef/streetmerchant/commit/6409646d57bf2b2bb5a4bcf8239740abed8edafb))
* `rateLimitTimeout` not being defaulted ([#106](https://www.github.com/jef/streetmerchant/issues/106)) ([28947be](https://www.github.com/jef/streetmerchant/commit/28947be9bc8981d7a45a5d0e69c18d039fcd9ed3))
* check response for rate limiting ([#58](https://www.github.com/jef/streetmerchant/issues/58)) ([#98](https://www.github.com/jef/streetmerchant/issues/98)) ([b7d9462](https://www.github.com/jef/streetmerchant/commit/b7d9462e794ef3961fb57c79ef8f66e77d25d20a))
* keep single `Store` from draining ([e819e46](https://www.github.com/jef/streetmerchant/commit/e819e46116d4e0b067a59791094b5cfbd2d7cd45))
* memory leak due to adblocker ([#139](https://www.github.com/jef/streetmerchant/issues/139)) ([0f6e570](https://www.github.com/jef/streetmerchant/commit/0f6e570cc817dfc10bcddc5743a0faf3b1489270))
* **nvidia:** false positives ([#132](https://www.github.com/jef/streetmerchant/issues/132)) ([a75d214](https://www.github.com/jef/streetmerchant/commit/a75d214dd555d5e0388cb54b15be324cc25b6a15))
* newegg out-of-stock ([#124](https://www.github.com/jef/streetmerchant/issues/124)) ([770a13a](https://www.github.com/jef/streetmerchant/commit/770a13ac3559401b430547908d1df014582c1e37))
* newegg out-of-stock labels ([#134](https://www.github.com/jef/streetmerchant/issues/134)) ([19c8f18](https://www.github.com/jef/streetmerchant/commit/19c8f188c796258c469c2b4c6461fc5da3907a47))
* **notification:** wrong condition for sounds playing ([#91](https://www.github.com/jef/streetmerchant/issues/91)) ([103d96d](https://www.github.com/jef/streetmerchant/commit/103d96dc81d6fd097fcdbed5bdd7487d7d73bf6e))
* **store:** false positives for nvidia. ([#85](https://www.github.com/jef/streetmerchant/issues/85)) ([c65fa04](https://www.github.com/jef/streetmerchant/commit/c65fa04666775060532e28076a0b4af50f8dd30b))
## [1.4.0](https://www.github.com/jef/streetmerchant/compare/v1.3.0...v1.4.0) (2020-09-19)
### Features
* **notification:** add mint mobile carrier ([#70](https://www.github.com/jef/streetmerchant/issues/70)) ([8aba7ec](https://www.github.com/jef/streetmerchant/commit/8aba7ecbdb0bfce06257b7b9066e8fccbd82e47e))
* **notification:** add pushover ([#55](https://www.github.com/jef/streetmerchant/issues/55)) ([c85658b](https://www.github.com/jef/streetmerchant/commit/c85658bf82fdf360e5e9d8345eaa846f0572e67c))
* **notification:** add telegram ([#71](https://www.github.com/jef/streetmerchant/issues/71)) ([393d5f6](https://www.github.com/jef/streetmerchant/commit/393d5f689887bf1d6f30a37eea163b2e6bbd4efa))
* **notification:** add telus sms ([6be74a1](https://www.github.com/jef/streetmerchant/commit/6be74a19f3d3f999145d17ac8e91c59db2502071))
* **store:** add amazon.ca, fix timeout ([#75](https://www.github.com/jef/streetmerchant/issues/75)) ([d4de1a4](https://www.github.com/jef/streetmerchant/commit/d4de1a4638e903eb9518354ab6fb2f8c4befc347))
* webpage toggle, sound notification, fix evga links ([#52](https://www.github.com/jef/streetmerchant/issues/52)) ([a217409](https://www.github.com/jef/streetmerchant/commit/a21740942bbbbe967948062fa06cfc82c31eb755))
### Performance Improvements ### Performance Improvements
* browser abstraction ([#68](https://www.github.com/jef/nvidia-snatcher/issues/68)) ([#81](https://www.github.com/jef/nvidia-snatcher/issues/81)) ([ebbdfe3](https://www.github.com/jef/nvidia-snatcher/commit/ebbdfe3f6378516112f4b6e004bbd6ccf13af685)) * browser abstraction ([#68](https://www.github.com/jef/streetmerchant/issues/68)) ([#81](https://www.github.com/jef/streetmerchant/issues/81)) ([ebbdfe3](https://www.github.com/jef/streetmerchant/commit/ebbdfe3f6378516112f4b6e004bbd6ccf13af685))
## [1.3.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.2.0...v1.3.0) (2020-09-19) ## [1.3.0](https://www.github.com/jef/streetmerchant/compare/v1.2.0...v1.3.0) (2020-09-19)
### Features ### Features
* **logging:** add timestamp ([#48](https://www.github.com/jef/nvidia-snatcher/issues/48)) ([6c3cd01](https://www.github.com/jef/nvidia-snatcher/commit/6c3cd016850d03a6c6a894cab24ba2d3781a9af1)) * **logging:** add timestamp ([#48](https://www.github.com/jef/streetmerchant/issues/48)) ([6c3cd01](https://www.github.com/jef/streetmerchant/commit/6c3cd016850d03a6c6a894cab24ba2d3781a9af1))
### Bug Fixes ### Bug Fixes
* **store:** amazon captcha false-positives ([#54](https://www.github.com/jef/nvidia-snatcher/issues/54)) ([5c9e0b6](https://www.github.com/jef/nvidia-snatcher/commit/5c9e0b6d06bd7e1223a7587fec067c8e79c9cfd6)) * **store:** amazon captcha false-positives ([#54](https://www.github.com/jef/streetmerchant/issues/54)) ([5c9e0b6](https://www.github.com/jef/streetmerchant/commit/5c9e0b6d06bd7e1223a7587fec067c8e79c9cfd6))
* evga xc3 ultra link ([#56](https://www.github.com/jef/nvidia-snatcher/issues/56)) ([d907092](https://www.github.com/jef/nvidia-snatcher/commit/d907092b443b056605e09cb2ca3e94e6ca811d9e)) * evga xc3 ultra link ([#56](https://www.github.com/jef/streetmerchant/issues/56)) ([d907092](https://www.github.com/jef/streetmerchant/commit/d907092b443b056605e09cb2ca3e94e6ca811d9e))
* screenshot size, add screenshot config setting ([#53](https://www.github.com/jef/nvidia-snatcher/issues/53)) ([7cfc7c7](https://www.github.com/jef/nvidia-snatcher/commit/7cfc7c74429c808fa14468cdd497eb9f9aeb922c)) * screenshot size, add screenshot config setting ([#53](https://www.github.com/jef/streetmerchant/issues/53)) ([7cfc7c7](https://www.github.com/jef/streetmerchant/commit/7cfc7c74429c808fa14468cdd497eb9f9aeb922c))
* sms carrier config, add google carrier ([#44](https://www.github.com/jef/nvidia-snatcher/issues/44)) ([971fec2](https://www.github.com/jef/nvidia-snatcher/commit/971fec20e441e2b12a38d5c8d17d2d4cb5e64d6b)) * sms carrier config, add google carrier ([#44](https://www.github.com/jef/streetmerchant/issues/44)) ([971fec2](https://www.github.com/jef/streetmerchant/commit/971fec20e441e2b12a38d5c8d17d2d4cb5e64d6b))
## [1.2.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.1.0...v1.2.0) (2020-09-19) ## [1.2.0](https://www.github.com/jef/streetmerchant/compare/v1.1.0...v1.2.0) (2020-09-19)
### Features ### Features
* **ci:** add `npm run build` ([faad3e6](https://www.github.com/jef/nvidia-snatcher/commit/faad3e68efafaab135b77080b02af83429b6eca6)) * **ci:** add `npm run build` ([faad3e6](https://www.github.com/jef/streetmerchant/commit/faad3e68efafaab135b77080b02af83429b6eca6))
* **store:** microcenter ([#39](https://www.github.com/jef/nvidia-snatcher/issues/39)) ([edf17e9](https://www.github.com/jef/nvidia-snatcher/commit/edf17e926f3d186e7630da2834d78de3e540a956)) * **store:** microcenter ([#39](https://www.github.com/jef/streetmerchant/issues/39)) ([edf17e9](https://www.github.com/jef/streetmerchant/commit/edf17e926f3d186e7630da2834d78de3e540a956))
* add Amazon links ([#26](https://www.github.com/jef/nvidia-snatcher/issues/26)) ([f0560ce](https://www.github.com/jef/nvidia-snatcher/commit/f0560ce72bfbfdd6360b85e23edaa875d58f228f)) * add Amazon links ([#26](https://www.github.com/jef/streetmerchant/issues/26)) ([f0560ce](https://www.github.com/jef/streetmerchant/commit/f0560ce72bfbfdd6360b85e23edaa875d58f228f))
* add email test, fix memory leak ([#24](https://www.github.com/jef/nvidia-snatcher/issues/24)) ([a2fb973](https://www.github.com/jef/nvidia-snatcher/commit/a2fb97333c6eb81250b24ccb6859e9356acded21)) * add email test, fix memory leak ([#24](https://www.github.com/jef/streetmerchant/issues/24)) ([a2fb973](https://www.github.com/jef/streetmerchant/commit/a2fb97333c6eb81250b24ccb6859e9356acded21))
* more Best Buy AIBs ([#41](https://www.github.com/jef/nvidia-snatcher/issues/41)) ([7d7bd18](https://www.github.com/jef/nvidia-snatcher/commit/7d7bd18b4dd656ec01ef2fb2d8519e2a7f34ef70)) * more Best Buy AIBs ([#41](https://www.github.com/jef/streetmerchant/issues/41)) ([7d7bd18](https://www.github.com/jef/streetmerchant/commit/7d7bd18b4dd656ec01ef2fb2d8519e2a7f34ef70))
* page timeout ([#22](https://www.github.com/jef/nvidia-snatcher/issues/22)) ([643045c](https://www.github.com/jef/nvidia-snatcher/commit/643045c7e0158fb6526bd09427b96cce7958bcea)) * page timeout ([#22](https://www.github.com/jef/streetmerchant/issues/22)) ([643045c](https://www.github.com/jef/streetmerchant/commit/643045c7e0158fb6526bd09427b96cce7958bcea))
* slack integration ([#34](https://www.github.com/jef/nvidia-snatcher/issues/34)) ([c0a881a](https://www.github.com/jef/nvidia-snatcher/commit/c0a881a16ebb573bf35b7f29cb27e5b3c2e1fe78)) * slack integration ([#34](https://www.github.com/jef/streetmerchant/issues/34)) ([c0a881a](https://www.github.com/jef/streetmerchant/commit/c0a881a16ebb573bf35b7f29cb27e5b3c2e1fe78))
* sms notification for usa carriers ([#40](https://www.github.com/jef/nvidia-snatcher/issues/40)) ([5a3636b](https://www.github.com/jef/nvidia-snatcher/commit/5a3636bcb639bb33bc586af96264f5df2f3a8307)) * sms notification for usa carriers ([#40](https://www.github.com/jef/streetmerchant/issues/40)) ([5a3636b](https://www.github.com/jef/streetmerchant/commit/5a3636bcb639bb33bc586af96264f5df2f3a8307))
* update to check if FE in-stock via Digital River ([#29](https://www.github.com/jef/nvidia-snatcher/issues/29)) ([00ede13](https://www.github.com/jef/nvidia-snatcher/commit/00ede13501082f530ea672a349816be1d31621a8)) * update to check if FE in-stock via Digital River ([#29](https://www.github.com/jef/streetmerchant/issues/29)) ([00ede13](https://www.github.com/jef/streetmerchant/commit/00ede13501082f530ea672a349816be1d31621a8))
### Bug Fixes ### Bug Fixes
* small error in `isOutOfStock` logic ([#33](https://www.github.com/jef/nvidia-snatcher/issues/33)) ([c2a210c](https://www.github.com/jef/nvidia-snatcher/commit/c2a210cc815c3aa06f6f14d33954f65577d95954)) * small error in `isOutOfStock` logic ([#33](https://www.github.com/jef/streetmerchant/issues/33)) ([c2a210c](https://www.github.com/jef/streetmerchant/commit/c2a210cc815c3aa06f6f14d33954f65577d95954))
## [1.1.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.0.0...v1.1.0) (2020-09-18) ## [1.1.0](https://www.github.com/jef/streetmerchant/compare/v1.0.0...v1.1.0) (2020-09-18)
### Features ### Features
* add conventional commits ([#14](https://www.github.com/jef/nvidia-snatcher/issues/14)) ([eb4f5e0](https://www.github.com/jef/nvidia-snatcher/commit/eb4f5e034176a286eabe381c98ced77cd197d7fb)) * add conventional commits ([#14](https://www.github.com/jef/streetmerchant/issues/14)) ([eb4f5e0](https://www.github.com/jef/streetmerchant/commit/eb4f5e034176a286eabe381c98ced77cd197d7fb))
* add evga ([#17](https://www.github.com/jef/nvidia-snatcher/issues/17)) ([#18](https://www.github.com/jef/nvidia-snatcher/issues/18)) ([6c65032](https://www.github.com/jef/nvidia-snatcher/commit/6c6503219f7c188783c24a44f7052b276a4b39a3)) * add evga ([#17](https://www.github.com/jef/streetmerchant/issues/17)) ([#18](https://www.github.com/jef/streetmerchant/issues/18)) ([6c65032](https://www.github.com/jef/streetmerchant/commit/6c6503219f7c188783c24a44f7052b276a4b39a3))
### Bug Fixes ### Bug Fixes
* exception handling `TimeoutError` ([#20](https://www.github.com/jef/nvidia-snatcher/issues/20)) ([#21](https://www.github.com/jef/nvidia-snatcher/issues/21)) ([00a0687](https://www.github.com/jef/nvidia-snatcher/commit/00a0687d3eba6a8fca871161b447529be00c8896)) * exception handling `TimeoutError` ([#20](https://www.github.com/jef/streetmerchant/issues/20)) ([#21](https://www.github.com/jef/streetmerchant/issues/21)) ([00a0687](https://www.github.com/jef/streetmerchant/commit/00a0687d3eba6a8fca871161b447529be00c8896))
## 1.0.0 (2020-09-18) ## 1.0.0 (2020-09-18)
### Features ### Features
* use ts, update cd, update `README` ([#12](https://www.github.com/jef/nvidia-snatcher/issues/12)) ([e9fc0bf](https://www.github.com/jef/nvidia-snatcher/commit/e9fc0bf5f770481d5e508d8b520e1020624e05d2)) * use ts, update cd, update `README` ([#12](https://www.github.com/jef/streetmerchant/issues/12)) ([e9fc0bf](https://www.github.com/jef/streetmerchant/commit/e9fc0bf5f770481d5e508d8b520e1020624e05d2))
+76
View File
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at jeffreylec@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
+10 -5
View File
@@ -1,5 +1,6 @@
# Build the source code FROM node:14.15.4-alpine3.12 AS builder
FROM node:15.0.1-alpine3.12 AS builder
LABEL org.opencontainers.image.source="https://github.com/jef/streetmerchant"
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
@@ -11,10 +12,10 @@ COPY tsconfig.json tsconfig.json
RUN npm ci RUN npm ci
COPY src/ src/ COPY src/ src/
RUN npm run build RUN npm run compile
RUN npm prune --production RUN npm prune --production
FROM node:15.0.1-alpine3.12 FROM node:14.15.4-alpine3.12
RUN apk add --no-cache chromium RUN apk add --no-cache chromium
@@ -32,5 +33,9 @@ WORKDIR /app
COPY --from=builder /build/node_modules/ node_modules/ COPY --from=builder /build/node_modules/ node_modules/
COPY --from=builder /build/build/ build/ COPY --from=builder /build/build/ build/
COPY web/ web/
COPY package.json package.json
COPY version.txt version.txt
CMD [ "node", "./build/index.js" ] ENTRYPOINT ["npm", "run"]
CMD ["start:production"]
+17
View File
@@ -0,0 +1,17 @@
.DEFAULT_GOAL := run
.PHONY: build
build:
docker-compose build streetmerchant
.PHONY: run
run:
docker-compose up
.PHONY: run-detached
run-detached:
docker-compose up -d
.PHONY: stop
stop:
docker-compose down
+40 -338
View File
@@ -1,346 +1,48 @@
# nvidia-snatcher [![ci](https://github.com/jef/nvidia-snatcher/workflows/ci/badge.svg)](https://github.com/jef/nvidia-snatcher/actions?query=workflow%3Aci) <p align="center">
<a href="https://jef.codes/streetmerchant"
><img
src="https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-banner.png"
alt="streetmerchant"
/></a>
</p>
<p align="center">
<strong>The world's easiest, most powerful stock checker</strong>
</p>
<p align="center">
<a href="https://github.com/jef/streetmerchant/actions?query=workflow%3ARelease"
><img src="https://github.com/jef/streetmerchant/workflows/Release/badge.svg"
/></a>
<a href="https://discord.gg/gbVY4vB9JF"
><img
src="https://img.shields.io/discord/773913070665859073.svg?label=chat&logo=discord&logoColor=ffffff&color=7389D8"
alt="Tweet"
/></a>
<a
href="https://twitter.com/intent/tweet?text=Beat%20the%20masses%20with%20streetmerchant&url=https://github.com/jef/streetmerchant&hashtags=typescript,opensource,bot,shopping"
><img
src="https://img.shields.io/badge/twitter-share-green?logo=twitter&style=social"
alt="Tweet"
/></a>
</p>
<p align="center">
<em>To get started, visit <a href="https://jef.codes/streetmerchant">jef.codes/streetmerchant</a></em>
</p>
[FAQ](#FAQ) | [Issues](https://github.com/jef/nvidia-snatcher/issues) | [Wiki](https://github.com/jef/nvidia-snatcher/wiki) ## Features
![nvidia-snatcher](media/screenshot.png) First and foremost, this service _will not_ automatically buy for you.
The purpose of this bot is to get an Nvidia card. It tries multiple things to do that. - **Checks stock continuously** -- runs 24/7, 365, looking for the items you want.
- **Ready for checkout** -- ability to add to cart when available and even opens the browser for you.
- **Notifications galore** -- when you're not by your computer, worry free with notifications to most platforms and devices when an item comes in stock.
- Currently, `nvidia-snatcher` is not capable of purchasing a card for you ## Quick start
- Scrapes multiple websites for patterns of being stocked
- API requests are a work in progress (very soon)
- Opens browser when stock is available
- Sends an email to you when stock is avaiable (must have Gmail)
<details> streetmerchant runs on Node.js 14:
<summary>What you may see if you're lucky</summary>
```sh ```shell
2020-09-18T07:06:28.535Z info :: ✖ [nvidia] nvidia founders edition is still out of stock git clone https://github.com/jef/streetmerchant.git
2020-09-18T07:06:31.241Z info :: ✖ [nvidia] nvidia founders edition is still out of stock cd streetmerchant && npm i && npm run start
2020-09-18T07:06:34.212Z info :: ✖ [bestbuy] nvidia founder edition is still out of stock
2020-09-18T07:06:39.878Z info :: ✖ [bandh] gigabyte black is still out of stock
2020-09-18T07:06:43.236Z info :: ✖ [bestbuy] gigabyte black is still out of stock
2020-09-18T07:06:43.318Z info :: ↗ trying stores again
2020-09-18T07:06:43.318Z info :: 🚀🚀🚀 [nvidia] nvidia founders edition IN STOCK 🚀🚀🚀
2020-09-18T07:06:43.318Z info :: https://store.nvidia.com/store/nvidia/en_US/buy/productID.5438481700/clearCart.yes/nextPage.QuickBuyCartPage
``` ```
</details> For more information and customization, visit [jef.codes/streetmerchant/getting-started](https://jef.codes/streetmerchant/getting-started).
| | Adorama | Amazon | Amazon (CA) | ASUS | B&H | Best Buy | Best Buy (CA) | EVGA | Micro Center | Newegg | Newegg (CA) | Nvidia | Office Depot | PNY | Zotac |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| **3070**| | | | | | `✔` | `✔` | | | | `✔` | | | `✔` | |
| **3080** | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` |
| **3090** | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | | `✔` | `✔` | `✔` | | `✔` | `✔` |
## Installation and prerequisites
Linux, macOS, and Windows are all capable operating systems.
You do not need any computer skills, smarts, or anything of that nature. You are very capable as you have made it this far. Some basic understanding how a terminal, git, and or Node.js is a bonus, but that does not limit you to getting `nvidia-snatcher` running!
### Quick overview
#### Native installation
- [Node.js 15](https://nodejs.org/en/)
- [git](https://git-scm.com/)
- Clone this project `git clone https://github.com/jef/nvidia-snatcher.git`
- Run `npm install`
- Copy `.env-example` to a new file `.env` and edit the `.env` file to your liking using your [favorite text editor](https://code.visualstudio.com/)
- More on this in [customization](#Customization)
- Run `npm run start` to start
At any point you want the program to stop, use <kbd>Ctrl</kbd> + <kbd>C</kbd>.
> :point_right: Please visit the [wiki](https://github.com/jef/nvidia-snatcher/wiki) if you need more help with installation.
#### Docker image (To run inside containers)
Available via GitHub Container Registry.
| Tag | Note |
|:---:|---|
| `latest` | Latest stable build |
| `nightly` | Latest HEAD build, could be unstable |
Use `docker run --cap-add=SYS_ADMIN -it --rm --env-file ./.env ghcr.io/jef/nvidia-snatcher:nightly` to run.
### Developer notes
The command `npm run start:dev` can be used instead of `npm run start` to automatically restart the project when filesystem changes are detected in the `src/` folder or `.env` file.
### Customization
To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _All environment variables are **optional**._
Here is a list of variables that you can use to customize your newly copied `.env` file:
| Environment variable | Description | Notes |
|:---:|---|---|
| `BROWSER_TRUSTED` | Skip Chromium Sandbox | Useful for containerized environments, default: `false` |
| `COUNTRY` | [Supported country](#supported-countries) you want to be scraped | Currently only used by Nvidia, default: `usa` |
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier) | Default: `false` |
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify | Can be comma separated, use role ID, E.g.: `<@2834729847239842>` |
| `DISCORD_WEB_HOOK` | Discord Web Hook URL | Can be comma separated, use whole webhook URL |
| `EMAIL_PASSWORD` | Gmail password | See below if you have MFA |
| `EMAIL_TO` | Destination Email | Defaults to username if not set. Can be comma separated |
| `EMAIL_USERNAME` | Gmail address | E.g.: `jensen.robbed.us@gmail.com` |
| `HEADLESS` | Puppeteer to run headless or not | Debugging related, default: `true` |
| `INCOGNITO` | Puppeteer to run incognito or not | Debugging related, default: `false` |
| `IN_STOCK_WAIT_TIME` | Time to wait between requests to the same link if it has that card in stock | In seconds, default: `0` |
| `LOG_LEVEL` | [Logging levels](https://github.com/winstonjs/winston#logging-levels) | Debugging related, default: `info` |
| `LOW_BANDWIDTH` | Blocks images/fonts to reduce traffic | Disables ad blocker, default: `false` |
| `MAX_PRICE_SERIES_3070` | Maximum price allowed for a match, applies 3070 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
| `MAX_PRICE_SERIES_3080` | Maximum price allowed for a match, applies 3080 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
| `MAX_PRICE_SERIES_3090` | Maximum price allowed for a match, applies 3090 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
| `MICROCENTER_LOCATION` | Specific MicroCenter location(s) to search | Comma separated, e.g.: `marietta,duluth`, default: `web` |
| `MQTT_BROKER_ADDRESS` | IP address or URL of MQTT Broker | e.g 192.168.1.xxx or broker.hivemq.com
| `MQTT_BROKER_PORT` | Network port of MQTT Broker | Default: 1883
| `MQTT_CLIENT_ID` | Unique ClientID (only if required by MQTT Broker), typically not required when only publishing alerts | eg. client-123456
| `MQTT_PASSWORD` | MQTT password - only use with MQTT brokers on private networks, if required. Will not be sent over public networks for safety. | e.g mysecret
| `MQTT_QOS` | QoS level for published alerts to broker (https://www.npmjs.com/package/mqtt#about-qos) | Default: 0, Can be 0, 1, or 2
| `MQTT_TOPIC` | Topic to publish alerts to. Can include %store%, %series%, %brand%, %model% for dynamic topics | Default: nvidia-snatcher/alert e.g nv-alert/%store%/%series%/%brand%/%model%/alert
| `MQTT_USERNAME` | MQTT username - (only if required by MQTT Broker) | e.g myusername
| `NVIDIA_ADD_TO_CART_ATTEMPTS` | The maximum number of times the `nvidia-api` add to cart feature will be attempted before failing | Default: `10` |
| `NVIDIA_SESSION_TTL` | The time in milliseconds to keep the cart active while using `nvidia-api` | Default: `60000` |
| `OPEN_BROWSER` | Toggle for whether or not the browser should open when item is found | Default: `true` |
| `PAGERDUTY_INTEGRATION_KEY` | PagerDuty Events API v2 Integration Key. Obtain one in PagerDuty - <Service you want to use> - Integrations | |
| `PAGERDUTY_SEVERITY` | Severity of PagerDuty events | Default: `info` |
| `PAGE_BACKOFF_MIN` | Minimum backoff time between retrying requests for the same store when a forbidden response is received | Default: `10000` |
| `PAGE_BACKOFF_MAX` | Maximum backoff time between retrying requests for the same store when a forbidden response is received | Default: `3600000` |
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same product page | In milliseconds, default: `5000` |
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same product page | In milliseconds, default: `10000` |
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds | `0` for infinite, default: `30000` |
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS | Email configuration required |
| `PHONE_NUMBER` | 10 digit phone number | E.g.: `1234567890`, email configuration required |
| `PLAY_SOUND` | Play this sound notification if a card is found | Relative path accepted, valid formats: wav, mp3, flac, E.g.: `path/to/notification.wav`, [free sounds available](https://notificationsounds.com/) |
| `PROXY_ADDRESS` | IP Address or fqdn of proxy server |
| `PROXY_PORT` | TCP Port number on which the proxy is listening for connections | Default: `80` |
| `PUSHBULLET` | PushBullet API key | Generate at https://www.pushbullet.com/#settings/account | |
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build | |
| `PUSHOVER_USER` | Pushover username | |
| `PUSHOVER_PRIORITY` | Pushover message priority |
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
| `SHOW_ONLY_BRANDS` | Filter to show specified brands | Comma separated, e.g.: `evga,zotac` |
| `SHOW_ONLY_MODELS` | Filter to show specified models | Both supported formats are comma separated <br/><br/>1. Standard E.g.: `founders edition,rog strix` <br/><br/> 2. Advanced E.g: `MODEL:SERIES`, E.g: `founders edition:3090,rog strix` |
| `SHOW_ONLY_SERIES` | Filter to show specified series | Comma separated, e.g.: `3080` |
| `SLACK_CHANNEL` | Slack channel for posting | E.g.: `update`, no need for `#` |
| `SLACK_TOKEN` | Slack API token | |
| `SMTP_ADDRESS` | IP Address or fqdn of smtp server |
| `SMTP_PORT` | TCP Port number on which the smtp server is listening for connections | Default: `25` |
| `STORES` | [Supported stores](#supported-stores) you want to be scraped | Both supported formats are comma separated <br/><br/>1. Standard E.g.: `"nvidia"` <br/><br/> 2. Advanced E.g: `STORE:PAGE_SLEEP_MIN:PAGE_SLEEP_MAX`, E.g: `nvidia:10000:30000` <br/><br/>Default: `nvidia` |
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
| `TELEGRAM_ACCESS_TOKEN` | Telegram access token | |
| `TELEGRAM_CHAT_ID` | Telegram chat ID | Comma seperated, e.g.: `123456789`, `123456789,987654321` |
| `TWILIO_ACCOUNT_SID` | Twilio Account SID | Can be found on twilio.com/console |
| `TWILIO_AUTH_TOKEN` | Twilio Auth Token | Can be found on twilio.com/console |
| `TWILIO_FROM_NUMBER` | Twilio provided phone number to send messages from | Include country code e.g +4401234567890 |
| `TWILIO_TO_NUMBER` | Mobile number to send SMS to | Include country code e.g +4401234567890 |
| `TWITTER_ACCESS_TOKEN_KEY` | Twitter Token Key | |
| `TWITTER_ACCESS_TOKEN_SECRET` | Twitter Token Secret | |
| `TWITTER_CONSUMER_KEY` | Twitter Consumer Key | Generate all Twitter keys at: https://developer.twitter.com/ |
| `TWITTER_CONSUMER_SECRET` | Twitter Consumer Secret | |
| `TWITTER_TWEET_TAGS` | Optional list of hashtags to append to the tweet message | E.g.: `#nvidia #nvidiastock` |
| `TWITCH_CLIENT_ID` | Twitch client ID | |
| `TWITCH_CLIENT_SECRET`| Twitch client secret | |
| `TWITCH_ACCESS_TOKEN` | Twitch access token | |
| `TWITCH_REFRESH_TOKEN` | Twitch refresh token | |
| `TWITCH_CHANNEL` | Twitch channel | |
| `USER_AGENT` | Custom User-Agents headers for HTTP requests | Newline separated, e.g.: `USER_AGENT_STRING1 \n USER_AGENT_STRING2` | | Default: `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36` |
| `WEB_PORT` | Starts a webserver to be able to control the bot while it is running; optional | Default: disabled |
> :point_right: If you have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
> :point_right: You can find your computer's user agent by [searching google for "my user agent"](http://google.com/search?q=my+user+agent)
> :point_right: You can test your notification configuration by running `npm run test:notification`.
> :point_right: Data usage is [known to be high](https://github.com/jef/nvidia-snatcher/issues?q=is%3Aissue+sort%3Aupdated-desc+bandwidth). This is expected as the program scrapes many websites in parallel 24/7. To help reduce this, use `LOW_BANDWIDTH="true"`. We are looking into other solutions as well, but is low priority.
#### Supported stores
| Stores | Environment variable |
|:---:|:---:|
| Adorama | `adorama`|
| Alternate (DE) | `alternate`|
| Alternate (NL) | `alternate-nl`|
| Amazon | `amazon`|
| Amazon (CA) | `amazon-ca`|
| Amazon (DE) | `amazon-de`|
| Amazon (ES) | `amazon-es`|
| Amazon (NL) | `amazon-nl`|
| Amazon (UK) | `amazon-uk`|
| Aria PC (UK) | `aria`|
| ASUS | `asus` |
| ASUS (DE) | `asus-de` |
| Azerty (NL) | `azerty`|
| B&H | `bandh`|
| Best Buy | `bestbuy`|
| Best Buy (CA) | `bestbuy-ca`|
| Box (UK) | `box`|
| Caseking (DE) | `caseking`|
| CCL (UK) | `ccl`|
| Computeruniverse (DE) | `computeruniverse` |
| Coolblue (NL) | `coolblue`|
| Coolmod (ES) | `coolmod`|
| Currys (UK) | `currys`|
| Cyberport (DE) | `cyberport` |
| eBuyer (UK) | `ebuyer`|
| EVGA | `evga`|
| EVGA (EU) | `evga-eu`|
| Gamestop | `gamestop`|
| Mediamarkt (DE) | `mediamarkt`|
| Micro Center | `microcenter`|
| Mindfactory (DE) | `mindfactory` |
| Newegg | `newegg`|
| Newegg (CA) | `newegg-ca`|
| Notebooksbilliger (DE) |`notebooksbilliger`|
| Novatech (UK) | `novatech`|
| Nvidia | `nvidia`|
| Nvidia (API) | `nvidia-api`|
| Office Depot | `officedepot`|
| Overclockers (UK) | `overclockers`|
| PCComponentes (ES) | `pccomponentes`|
| PNY | `pny`|
| Proshop (DE) | `proshop-de`|
| Proshop (DK) | `proshop-dk`|
| Saturn (DE) | `saturn`|
| Scan (UK) | `scan`|
| Very (UK) | `very`|
| Zotac | `zotac`|
<details>
<summary>Micro Center stores</summary>
> :point_right: Before using `web`, please review [this issue comment](https://github.com/jef/nvidia-snatcher/issues/442#issuecomment-703297393).
| Store name |
|:---:|
| `brooklyn` |
| `brentwood` |
| `cambridge` |
| `chicago` |
| `columbus` |
| `dallas` |
| `denver` |
| `duluth` |
| `fairfax` |
| `flushing` |
| `houston` |
| `madison-heights` |
| `marietta` |
| `mayfield-heights` |
| `north-jersey` |
| `overland-park` |
| `parkville` |
| `rockville` |
| `sharonville` |
| `st-davids` |
| `st-louis-park` |
| `tustin` |
| `westbury` |
| `westmont` |
| `yonkers` |
</details>
#### Supported Brands and Models
| Brand | Model |
|:---:|---|
| `asus` | `dual`, `dual oc`, `rog strix`, `rog strix oc`, `tuf`, `tuf oc` |
| `evga` | `ftw3`, `ftw3 ultra`, `xc3`, `xc3 black`, `xc3 ultra` |
| `gainward` | `phantom gs`, `phoenix`, `phoenix gs`, `phoenix gs oc` |
| `gigabyte` | `aorus master`, `aorus xtreme`, `eagle`, `eagle oc`, `gaming`, `gaming oc`, `turbo`, `vision`, `vision oc` |
| `inno3d` | `gaming x3`, `ichill x3`, `ichill x4`, `twin x2 oc` |
| `kfa2` | `sg oc` |
| `msi` | `gaming x trio`, `ventus 2x oc`, `ventus 3x`, `ventus 3x oc` |
| `nvidia` | `founders edition` |
| `palit` | `gamerock oc`, `gaming pro`, `gaming pro oc` |
| `pny` | `dual fan`, `xlr8`, `xlr8 rgb` |
| `zotac` | `amp holo`, `amp extreme holo`, `trinity`, `trinity oc`, `twin edge`, `twin edge oc` |
#### Supported carriers
| Carrier | Environment variable | Notes |
|:---:|:---:|:---:|
| AT&T | `att` | |
| AT&T Prepaid | `attgo` | |
| Bell | `bell` | |
| Fido | `fido` | |
| Google | `google`| |
| Koodo | `koodo` | |
| Mint | `mint`| |
| Rogers | `rogers` | |
| Sprint | `sprint`| |
| Telus | `telus`| |
| T-Mobile | `tmobile`| |
| Verizon | `verizon`| Works with Visible |
| Virgin | `virgin`| |
| Virgin (CA) | `virgin-ca`| |
#### Supported countries
`COUNTRY` is only used by the `nvidia` and `nvidia-api` stores.
| Country | 3080 FE | 3090 FE | Test Card | Notes |
|:---:|:---:|:---:|:---:|:---:|
| austria | `✔` | `✔` | `✔` | |
| belgium | `✔` | `✔` | `✔` | |
| canada | `✔` | `✔` | `✔` | |
| czechia | `✔` | `✔` | `✔` | |
| denmark | `✔` | | `✔` | Missing RTX 3090 |
| finland | `✔` | | `✔` | Missing RTX 3090 |
| france | `✔` | `✔` | `✔` | |
| germany | `✔` | `✔` | `✔` | |
| great_britain | `✔` | `✔` | `✔` | |
| ireland | `✔` | `✔` | `✔` | |
| italy | `✔` | `✔` | `✔` | |
| luxembourg | `✔` | `✔` | `✔` | |
| netherlands | `✔` | `✔` | `✔` | |
| norway | `✔` | `✔` | `✔` | |
| poland | `✔` | `✔` | `✔` | |
| portugal | `✔` | | | RTX 3080 only |
| spain | `✔` | `✔` | `✔` | |
| sweden | `✔` | `✔` | `✔` | |
| usa | `✔` | `✔` | `✔` | |
## FAQ
**Q: What's Node.js and how do I install it?** Visit [their website](https://nodejs.org/en/) and download and install it. Very straight forward. Otherwise, Google more information related to your system needs.
**Q: Will this harm my computer?** No.
**Q: Have you gotten a card yet?** YES! :tada: :rocket:
<details>
<summary>Screenshot</summary>
![screenshot](https://i.imgur.com/59CRzGq.png)
</details>
**Q: Will I get banned from of the stores?** Perhaps, but getting a card is a nice outcome.
**Q: I got a problem and need help!** Join the [Discord](https://discord.gg/Cyc7nrz) or file an [issue](https://github.com/jef/nvidia-snatcher/issues/new/choose), I'll do my best to get to you. I work a full time job and this is only a hobby of mine.
**Q: How do I get the latest code?** Take look at this [wiki page](https://github.com/jef/nvidia-snatcher/wiki/Troubleshoot:-General:-Getting-the-latest-code)
**Q: Why don't my notifications work?** There are probably an [issue](https://github.com/jef/nvidia-snatcher/issues?q=is%3Aissue+sort%3Aupdated-desc+sound+is%3Aclosed) [that] has [already](https://github.com/jef/nvidia-snatcher/issues/182) [been](https://github.com/jef/nvidia-snatcher/issues/116) [resolved](https://github.com/jef/nvidia-snatcher/issues/155)
**Q: I'd love to contribute, how do I do that?** Make a [pull request](https://github.com/jef/nvidia-snatcher/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)! All contributions are welcome.
**Q: Why do I have to download all this stuff just to get this bot working?** Well, I would rather you didn't either. See [#11](https://github.com/jef/nvidia-snatcher/issues/11).
### Acknowledgements
Thanks to the great contributors that make this project possible
Special shout to initial developers:
- [@andirew](https://github.com/andirew)
- [@fuckingrobot](https://github.com/fuckingrobot)
- [@ioncaza](https://github.com/IonCaza)
- [@malbert69](https://github.com/malbert69)
+10
View File
@@ -0,0 +1,10 @@
version: '3.0'
services:
streetmerchant:
image: ghcr.io/jef/streetmerchant:latest
build:
context: .
dockerfile: Dockerfile
container_name: streetmerchant
env_file:
- dotenv
+11
View File
@@ -0,0 +1,11 @@
# About
## Background
Remember on September 17th, 2020 at 9 AM EST the Nvidia site went from **Notify Me** to **Out of Stock** instantly? Well, they didn't sell any cards. The real reason was that they weren't ready to sell them to us yet. That's right, they turned off their third party storefronts because they were being overloaded with our clicks. They still kept the other cards that use those APIs online, but they removed that one. It was re-enabled at some point for a brief moment, but the same thing happened -- servers overloaded with API requests.
This is where streetmerchant comes in. It doesn't buy anything for you, but it makes it more of a stress free job to refresh and check sites while you go about your daily business. People took off work, missed appointments, and gave up other lively needs in hopes to buy a _graphics card_. Now we reach beyond graphics cards in hopes for other products!
Please enjoy,
jef
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

+1
View File
@@ -0,0 +1 @@
../CHANGELOG.md
+67
View File
@@ -0,0 +1,67 @@
# FAQ
## What's Node.js and how do I install it?
Visit [their website](https://nodejs.org/en/) and download and install it. Very straight forward. Otherwise, Google more information related to your system needs.
## Will this harm my computer?
No.
## Have you gotten a card yet?
[Sure did!](https://i.imgur.com/59CRzGq.png)
## Will I get banned from of the stores?
Perhaps, but it's the risk we're willing to take! To help minimize this, take a look at [#1050](https://github.com/jef/streetmerchant/issues/1050).
## I got a problem and need help
File an [issue](https://github.com/jef/streetmerchant/issues/new/choose). I'll do my best to get to you. I work a full time job and this is only a hobby of mine.
## How do I get the latest code?
Run the following commands:
```shell
git pull origin main
npm install
npm run start
```
If you changed the code at all, this will most likely fail. You can clear out your changes by doing:
```shell
git checkout .
git pull origin main
npm install
npm run start
```
You can also to [git-stash](https://git-scm.com/docs/git-stash), but we won't expand on that here.
## Why don't my notifications work?
There is probably an [issue](https://github.com/jef/streetmerchant/issues?q=is%3Aissue+sort%3Aupdated-desc+sound+is%3Aclosed) that has [already](https://github.com/jef/streetmerchant/issues/182) [been](https://github.com/jef/streetmerchant/issues/116) [resolved](https://github.com/jef/streetmerchant/issues/155).
## I'd love to contribute, how do I do that?
Make a [pull request](https://github.com/jef/streetmerchant/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)! All contributions are welcome.
## How do I add a store?
Here's a little write-up I did: [Adding a store](help/general.md#adding-a-store).
## Why do I have to download all this stuff just to get this bot working?
Well, I would rather you didn't either. See [#11](https://github.com/jef/streetmerchant/issues/11).
## Why does Amazon show an error page (with a picture of an animal) instead of adding to cart or going to the detail page?
This is intended; see [#733](https://github.com/jef/streetmerchant/issues/733). This indicates that the item is out of stock and only available from a third-party seller (often at a markup).
## I'm using streetmerchant in the cloud and X isn't working.
There is _a lot_ of undefined behavior with using streetmerchant in the cloud. Some sites may block IPs from your cloud provider. It is possible that a VPN will help circumvent these problems.
+105
View File
@@ -0,0 +1,105 @@
# Getting started
You do not need any computer skills, smarts, or anything of that nature. You are very capable as you have made it this far. Some basic understanding how a terminal, git, and or Node.js is a bonus, but that does not limit you to getting streetmerchant running!
## Prerequisites
- [git](https://git-scm.com/)
- Either [Node.js 14](https://nodejs.org/en/) or [Docker (1.13.0+)](https://docs.docker.com/get-docker/) (advanced users)
## Using Node.js
| Reference | Note |
|:---:|---|
| tag | Example, `v1.0.0`; stable |
| `main` | Latest HEAD; not tagged, could be unstable |
1. Download [Node.js 14](https://nodejs.org/en/)
1. Clone this project `git clone https://github.com/jef/streetmerchant.git`.
1. To checkout a particular reference, use `git checkout <ref name>` after cloning.
1. Navigate to this project by entering `cd streetmerchant`.
1. Run `npm install`.
1. Make a copy of `dotenv-example` and name it `dotenv`.
1. Edit the `dotenv` file to your liking using a text editor (like [vscode](https://code.visualstudio.com/)).
1. Run `npm run start` to start.
At any point you want the program to stop, use ++ctrl+c++.
???+ tip
Community based help can also be found on the [wiki](https://github.com/jef/streetmerchant/wiki). Feel free to check that out if you're having problems running. If you're still having problems running, you're probably not the first. Make some searches through the [GitHub issues](https://github.com/jef/streetmerchant/issues) before making one.
## Using Docker
Available via GitHub Container Registry.
| Tag | Note |
|:---:|---|
| `latest` | Latest release; stable |
| `nightly` | Latest HEAD each day at midnight UTC; could be unstable |
```sh
# to run docker nightly
docker run -it --rm \
--env-file ./dotenv \
ghcr.io/jef/streetmerchant:nightly
# to test notifications
docker run -it --rm \
--env-file ./dotenv \
ghcr.io/jef/streetmerchant:nightly test:notification:production
```
See [Developing in docker](#developing-in-docker) for more information
## Customization
To customize streetmerchant, make a copy of `dotenv-example` as `dotenv` and make any changes to your liking. View [Reference](reference/application.md) for more information on variables and their usage.
???+ tip
All environment variables are optional.
## For developers
### Developing in Node.js
The command `npm run start:dev` can be used instead of `npm run start` to automatically restart the project when filesystem changes are detected in the `src/` folder or `dotenv` file.
Use `npm run lint` to see any linting uses and `npm run fix` to automatically fix the issues it can.
### Developing in Docker
#### Prerequisites
- [Docker (1.13.0+)](https://docs.docker.com/get-docker/)
- [GNU Make](https://www.gnu.org/software/make/)
- Optional, but increases quality of life
- [Docker Compose](https://docs.docker.com/compose/install/)
- Depending on your system, you may already have this. Check before installing.
#### Starting with `docker-compose`
1. Make a copy of `dotenv-example` and name it `dotenv`.
1. Edit the `dotenv` file to your liking using a text editor (like [vscode](https://code.visualstudio.com/)).
1. If you're using `make`, you can run `make run` to start and `make stop` to stop.
1. There are more options in the `Makefile`, feel free to explore.
1. If you do not have `make`, you can run `docker-compose` directly:
```shell
# To start
# Use `-d` if you want to run in detached mode
# Use `--build` if you want to build the image before running (default image is latest in GitHub Container Registry).
docker-compose up
# To break down
docker-compose down
```
???+ note
If you are using `WEB_PORT`, then you will need to add the following to docker-compose:
```
ports:
- "<WEB_PORT>:<WEB_PORT>"
```
Replace `<WEB_PORT>` with the value you gave in your `dotenv`.
+133
View File
@@ -0,0 +1,133 @@
# General
## Adding a store
???+ note
This is subject to change in the future
In the following examples, I will be using "NewStore" as the store I'm wanting to add.
### Creating a store file
First, create a TypeScript file in `src/store/model`. In this example, I'll create a file named `new-store.ts`. At this point, you can copy and paste any of the other stores and change accordingly.
#### How to grab a container (aka selector)
For the containers, what you'll wanna do is use <kbd>F12</kbd> on the site you want to Inspect and click this button
![image](https://user-images.githubusercontent.com/12074633/100685326-2669da80-334a-11eb-93a9-8ac2c659f5f3.png)
Hover over the item you want and it should give you the context:
![image](https://user-images.githubusercontent.com/12074633/100685310-1e119f80-334a-11eb-91aa-b77b0ff6c2b1.png)
You can also right-click on any website element and select 'Inspect'. That should also give you the same results.
Some people will decide to choose a parent element as it can be unique. Like this case!
I'd rather use `.button.spin-button.prod-ProductCTA--primary.button--primary` instead of `.spin-button-children` as there are probably other elements on the page that are also `.spin-button-children`.
The reason why we use these selectors anyway is to wait for the webpage to load these specific elements, to help eliminate false positives.
For easily getting the selector, you can also copy it by right clicking on the tag, Copy > Copy selector.
![image](https://user-images.githubusercontent.com/12074633/100933096-d2323800-34ba-11eb-8f06-d106f43b7ad3.png)
### Updating the models
You'll now want to add the new store to `src/store/model/index.ts`.
This is what it will look like:
```diff
--- a/src/store/model/index.ts
+++ b/src/store/model/index.ts
@@ -48,6 +48,7 @@ import {MicroCenter} from './microcenter';
import {Mindfactory} from './mindfactory';
import {Newegg} from './newegg';
import {NeweggCa} from './newegg-ca';
+import {NewStore} from './new-store';
import {Notebooksbilliger} from './notebooksbilliger';
import {Novatech} from './novatech';
import {Nvidia} from './nvidia';
@@ -123,6 +124,7 @@ export const storeList = new Map([
[Mindfactory.name, Mindfactory],
[Newegg.name, Newegg],
[NeweggCa.name, NeweggCa],
+ [NewStore.name, NewStore],
[Notebooksbilliger.name, Notebooksbilliger],
[Novatech.name, Novatech],
[Nvidia.name, Nvidia],
```
After that, you're pretty much set. If you plan on adding new models or series, you will have to add them to `src/store/model/store.ts` and `src/config.ts`.
Here's an example:
```diff
--- a/src/store/model/store.ts
+++ b/src/store/model/store.ts
@@ -23,6 +23,7 @@ export type Brand =
| 'kfa2'
| 'microsoft'
| 'msi'
+ | 'new brand'
| 'nvidia'
| 'palit'
| 'pny'
@@ -37,6 +38,7 @@ export type Series =
| '3070'
| '3080'
| '3090'
+ | 'new series'
| 'rx6800'
| 'rx6800xt'
| 'rx6900xt'
@@ -83,6 +85,7 @@ export type Model =
| 'ichill x2'
| 'ichill x3'
| 'ichill x4'
+ | 'new model'
| 'nitro+'
| 'nitro oc se'
| 'nitro oc'
```
```diff
--- a/src/config.ts
+++ b/src/config.ts
@@ -308,6 +308,7 @@ const store = {
country: envOrString(process.env.COUNTRY, 'usa'),
maxPrice: {
series: {
+ 'new series': -1,
'3060ti': envOrNumber(process.env.MAX_PRICE_SERIES_3060TI),
3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070),
3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080),
@@ -337,6 +338,7 @@ const store = {
};
}),
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, [
+ 'new series',
'3060ti',
'3070',
'3080',
```
And voila! You're done! If you'd like to contribute to the project, feel free to create a [Pull Request](https://github.com/jef/streetmerchant/compare)! Don't forget to add the store (and brand, model, and series if you added) to the `README.md`.
???+ tip
Here's an [example](https://github.com/jef/streetmerchant/commit/af96c5f2e808af7496f3c3299e4cf173105de48b). If you'd like to include a max price, you can add `MAX_PRICE_SERIES_NEW_SERIES` to the above instead of the `-1`.
## Creating a Discord webhook
Take a look at Discord's [Intro to Webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks), that should get you going.
This is the main portion:
![image](https://user-images.githubusercontent.com/12074633/101225522-a4d2bf00-365f-11eb-8c35-d0f013e561d6.png)
![image](https://user-images.githubusercontent.com/12074633/101225550-b87e2580-365f-11eb-8be6-48b324b37916.png)
Use the full URL that you just copied and set that value to `DISCORD_WEB_HOOK`.
+42
View File
@@ -0,0 +1,42 @@
# Troubleshoot
## Captcha issues
### Option 1
If you're running into problems, try running in headful mode: `HEADLESS="false"`.
This will open a browser and run streetmerchant. Note that this isn't a great solution for those running in a headless environment, i.e.: VPS, cloud, docker. Instead, it would be a good solution for those running on separate computer that won't be blocked by running in the background.
### Option 2
As a last case scenario, use `PUPPETEER_EXECUTABLE_PATH`. This will use your computer's Chrome browser. You can run this is headless or headful mode.
> From the puppeteer doc:
>
> `PUPPETEER_EXECUTABLE_PATH` - specify an executable path to be used in `puppeteer.launch`. See [puppeteer.launch([options])](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions) on how the executable path is inferred. **BEWARE**: Puppeteer is only [guaranteed to work](https://github.com/puppeteer/puppeteer/#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.
For example:
`dotenv`:
```
PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable
```
This will vary depending on your operating system and install path. Please use full paths.
## macOS code signing
If you're getting a popup like this:
![image](https://user-images.githubusercontent.com/12074633/93616357-a36bf180-f9a2-11ea-82fa-da2a44807802.png)
Then run this command:
```sh
sudo codesign --force --deep --sign - ./node_modules/puppeteer/.local-chromium/mac-800071/chrome-mac/Chromium.app
```
???+ tip
The `mac-800071` may be different on your machine, so I would start from `./node_modules/puppeteer/.local-chromium` and auto complete from there.
+38
View File
@@ -0,0 +1,38 @@
[![streetmerchant](assets/images/streetmerchant-banner.png)](https://jef.codes/streetmerchant)
## Features
First and foremost, this service _will not_ automatically buy for you.
- **Checks stock continuously** -- runs 24/7, 365, looking for the items you want.
- **Ready for checkout** -- ability to add to cart when available and even opens the browser for you.
- **Notifications galore** -- when you're not by your computer, worry free with notifications to most platforms and devices when an item comes in stock.
## Getting started
You'll find most of the content on the left sidebar. The right sidebar will help you navigate a page.
### Contributing
- Give helpful tips and tricks to the [community based wiki](https://github.com/jef/streetmerchant/wiki).
- Add to the documentation through [pull requests](https://github.com/jef/streetmerchant/pulls).
- Fork and make a pull request to the repository.
### Looking for help
- Have an idea, question, or need help? Visit our [GitHub discussion board](https://github.com/jef/streetmerchant/discussions).
- Ran into a bug? File a [GitHub issue](https://github.com/jef/streetmerchant/issues/new/choose).
- Looking to hang out and talk shop? Join us on [Discord](https://discord.gg/gbVY4vB9JF).
### Supporting the project
The best way to support me is to donate to [Diabetes Research Institute](https://www.diabetesresearch.org/Give).
> The Diabetes Research Institute leads the world in cure-focused diabetes research.
>
> [diabetesresearch.org](https://www.diabetesresearch.org/about-DRI)
If you feel inclined to support me directly, here are those options:
- [GitHub Sponsors](https://github.com/sponsors/jef)
- [Paypal](https://www.paypal.me/jxf)
+6
View File
@@ -0,0 +1,6 @@
app.document$.subscribe(() => {
const tables = document.querySelectorAll('article table');
tables.forEach(table => {
new Tablesort(table);
});
});
+30
View File
@@ -0,0 +1,30 @@
{% extends "base.html" %}
{% block extrahead %}
{% set title = config.site_name %}
{% if page and page.meta and page.meta.title %}
{% set title = title ~ " - " ~ page.meta.title %}
{% elif page and page.title and not page.is_homepage %}
{% set title = title ~ " - " ~ page.title | striptags %}
{% endif %}
{% set image = config.site_url ~ '/assets/images/streetmerchant-github.png' %}
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ config.site_description }}" />
<meta property="og:url" content="{{ page.canonical_url }}" />
<meta property="og:image" content="{{ image }}" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1280" />
<meta property="og:image:height" content="640" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@hijxf" />
<meta name="twitter:creator" content="@hijxf" />
<meta name="twitter:title" content="{{ title }}" />
<meta name="twitter:description" content="{{ config.site_description }}" />
<meta name="twitter:image" content="{{ image }}" />
{% endblock %}
+29
View File
@@ -0,0 +1,29 @@
# Application
| Environment variable | Description |
|:---:|---|
| `AUTO_ADD_TO_CART` | Enable auto add to cart on support stores, default: `true` |
| `BROWSER_TRUSTED` | Skip Chromium Sandbox. Useful for containerized environments, default: `false` |
| `HEADLESS` | Puppeteer to run headless or not. Debugging related, default: `true` |
| `INCOGNITO` | Puppeteer to run incognito or not. Debugging related, default: `false` |
| `IN_STOCK_WAIT_TIME` | Time to wait between requests to the same link if it has that card in stock. In seconds, default: `0` |
| `LOG_LEVEL` | [Logging levels](https://github.com/winstonjs/winston#logging-levels). Debugging related, default: `info` |
| `LOW_BANDWIDTH` | Blocks images/fonts to reduce traffic. Disables ad blocker, default: `false` |
| `OPEN_BROWSER` | Toggle for whether or not the browser should open when item is found. Default: `true` |
| `PAGE_BACKOFF_MIN` | Minimum backoff time between retrying requests for the same store when a forbidden response is received. Default: `10000` |
| `PAGE_BACKOFF_MAX` | Maximum backoff time between retrying requests for the same store when a forbidden response is received. Default: `3600000` |
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same product page. In milliseconds, default: `5000` |
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same product page. In milliseconds, default: `10000` |
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds. `0` for infinite, default: `30000` |
| `PROXY_PROTOCOL` | Protocol of proxy server, such as `socks5`. Default: `http` |
| `PROXY_ADDRESS` | IP Address or fqdn of proxy server |
| `PROXY_PORT` | TCP Port number on which the proxy is listening for connections. Default: `80` |
| `SCREENSHOT` | Capture screenshot of page if a card is found. Default: `true` |
| `WEB_PORT` | Starts a webserver to be able to control the bot while it is running. Setting this value starts this service. |
???+ info
There is more information on proxy settings in the [Proxy documentation](proxy.md).
???+ tip
- You can also have a list of proxies that are rotated while searching stores. Proxies can be read from a file named `STORENAME.proxies` in the format of `socks5://username:password@ip`; one per line.
- Data usage is [known to be high](https://github.com/jef/streetmerchant/issues?q=is%3Aissue+sort%3Aupdated-desc+bandwidth). This is expected as the program scrapes many websites in parallel 24/7. To help reduce this, use `LOW_BANDWIDTH="true"`. We are looking into other solutions as well, but is low priority.
+265
View File
@@ -0,0 +1,265 @@
# Filter
| Environment variable | Description |
|:---:|---|
| `COUNTRY` | [Supported country](#supported-countries) you want to be scraped | Only used with `nvidia-api`, default: `usa` |
| `MAX_PRICE_SERIES_3060TI` | Maximum price allowed for a match, applies 3060 Ti series cards (does not apply to these sites: Nvidia, Asus, EVGA) |
| `MAX_PRICE_SERIES_3070` | Maximum price allowed for a match, applies 3070 series cards (does not apply to these sites: Nvidia, Asus, EVGA) |
| `MAX_PRICE_SERIES_3080` | Maximum price allowed for a match, applies 3080 series cards (does not apply to these sites: Nvidia, Asus, EVGA) |
| `MAX_PRICE_SERIES_3090` | Maximum price allowed for a match, applies 3090 series cards (does not apply to these sites: Nvidia, Asus, EVGA) |
| `MAX_PRICE_SERIES_CORSAIR_SF` | Maximum price allowed for a match, applies to Corsair PSUs |
| `MAX_PRICE_SERIES_DARKHERO` | Maximum price allowed for a match, applies to ASUS Dark Hero motherboards |
| `MAX_PRICE_SERIES_RYZEN5600` | Maximum price allowed for a match, applies AMD 5600 series cpus |
| `MAX_PRICE_SERIES_RYZEN5800` | Maximum price allowed for a match, applies AMD 5800 series cpus |
| `MAX_PRICE_SERIES_RYZEN5900` | Maximum price allowed for a match, applies AMD 5900 series cpus |
| `MAX_PRICE_SERIES_RYZEN5950` | Maximum price allowed for a match, applies AMD 5950 series cpus |
| `MAX_PRICE_SERIES_RX6800` | Maximum price allowed for a match, applies AMD RX 6800 |
| `MAX_PRICE_SERIES_RX6800XT` | Maximum price allowed for a match,applies AMD RX 6800 XT |
| `MAX_PRICE_SERIES_RX6900XT` | Maximum price allowed for a match, applies AMD RX 6900 XT |
| `MAX_PRICE_SERIES_SONYPS5C` | Maximum price allowed for a match, applies PS5 console |
| `MAX_PRICE_SERIES_SONYPS5DE` | Maximum price allowed for a match, applies PS5 digital edition |
| `MAX_PRICE_SERIES_XBOXSS` | Maximum price allowed for a match, applies PS5 digital edition |
| `MAX_PRICE_SERIES_XBOXSX` | Maximum price allowed for a match, applies PS5 digital edition |
| `MAX_PRICE_SERIES_TEST` | Maximum price allowed for a match, applies `test:series` |
| `MICROCENTER_LOCATION` | Specific MicroCenter location(s) to search. Comma separated, e.g.: `marietta,duluth`, default: `web` |
| `NVIDIA_ADD_TO_CART_ATTEMPTS` | The maximum number of times the `nvidia-api` add to cart feature will be attempted before failing. Default: `10` |
| `NVIDIA_SESSION_TTL` | The time in milliseconds to keep the cart active while using `nvidia-api`. Default: `60000` |
| `SHOW_ONLY_BRANDS` | Filter to show specified brands. Comma separated, e.g.: `evga,zotac` |
| `SHOW_ONLY_MODELS` | Filter to show specified models. Comma separated, can include series. E.g.: `founders edition:3090,rog strix` |
| `SHOW_ONLY_SERIES` | Filter to show specified series. Comma separated, e.g.: `3080,ryzen5900` |
| `STORES` | [Supported stores](#supported-stores) you want to be scraped. Default: `amazon,bestbuy`. Comma separated, can include `PAGE_SLEEP_MIN` and `PAGE_SLEEP_MAX` values. E.g.: `amazon:10000:30000,bestbuy,newegg:50000:80000`. |
???+ note
For `MAX_PRICE_SERIES_*` variables: enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods). E.g.: `1234`. Merchandise found above this price will be skipped.
## Supported stores
Used with the `STORES` variable.
| Stores | Country | Environment variable |
|---|---|---|
| AComPC | DE | `acompc` |
| Adorama | US | `adorama`|
| Akinformatica | IT | `akinformatica`|
| Allneeds | AU | `allneeds`|
| Alternate | DE | `alternate`|
| Alternate | NL | `alternate-nl`|
| Amazon | US | `amazon`|
| Amazon | CA | `amazon-ca`|
| Amazon | DE | `amazon-de`|
| Amazon Warehouse | DE | `amazon-de-warehouse`|
| Amazon | ES | `amazon-es`|
| Amazon | FR | `amazon-fr`|
| Amazon | IT | `amazon-it`|
| Amazon | NL | `amazon-nl`|
| Amazon | SG | `amazon-sg`|
| Amazon | UK | `amazon-uk`|
| AMD | US | `amd`|
| AMD | CA | `amd-ca`|
| AMD | DE | `amd-de`|
| AMD | IT | `amd-it`|
| AMD | UK | `amd-uk`|
| AntOnline | US | `antonline`|
| Argos | UK | `argos`|
| Argos | IE | `argos-ie`|
| Aria PC | UK | `aria`|
| ARLT | DE | `arlt`|
| ASUS | US | `asus` |
| ASUS | DE | `asus-de` |
| AWD-IT | UK | `awd` |
| Azerty | NL | `azerty`|
| B&H | US | `bandh`|
| Best Buy | US | `bestbuy`|
| Best Buy | CA | `bestbuy-ca`|
| Box | UK | `box`|
| BPCTech | AU | `bpctech`|
| BPM-Power | IT | `bpm-power`|
| CanadaComputers | CA | `canadacomputers` |
| Caseking | DE | `caseking`|
| CCL | UK | `ccl`|
| Centrecom | AU | `centrecom`|
| Comet | IT | `comet`|
| ComputerAlliance | AU | `computeralliance`|
| Computeruniverse | DE | `computeruniverse` |
| Coolblue | NL | `coolblue`|
| Coolmod | ES | `coolmod`|
| Corsair | US | `corsair`|
| CPL | AU | `cpl`|
| Currys | UK | `currys`|
| Cyberport | DE | `cyberport` |
| DComp | AU | `dcomp`|
| Drako | IT | `drako` |
| EBGames | CA | `ebgames`|
| eBuyer | UK | `ebuyer`|
| El Corte Inglés | ES | `elcorteingles`|
| ePrice | IT | `eprice`|
| Euronics | IT | `euronics`|
| Euronics | DE | `euronics-de`|
| Equippr | DE | `equippr`|
| Evatech | AU | `evatech`|
| EVGA | US | `evga`|
| EVGA | EU | `evga-eu`|
| Expert | DE | `expert`|
| Futurex | DE | `futurex`|
| Galaxus | DE | `galaxus`|
| Game | UK | `game`|
| Gamestop | US | `gamestop`|
| Gamestop | DE | `gamestop-de`|
| Gamestop | IE | `gamestop-ie`|
| Gamestop | IT | `gamestop-it`|
| HarrisTechnology | AU | `harristechnology`|
| Harvey Normans | IE | `harveynorman-ie` |
| Hardware Planet | IT | | `hardware-planet` |
| iGame Computer | AU | `igame-computer`|
| John Lewis | UK | `johnlewis`|
| Kabum | BR | `kabum`|
| Landmark Computers | AU | `landmark-computers`|
| Mediamarkt | DE | `mediamarkt`|
| Medimax | DE | `medimax`|
| Megekko | NL | `megekko`|
| MemoryExpress | CA | `memoryexpress`|
| Micro Center | US | `microcenter`|
| Mindfactory | DE | `mindfactory` |
| MSY | AU | `msy`|
| Mwave | AU | `mwave`|
| Newegg | US | `newegg`|
| Newegg | CA | `newegg-ca`|
| Newegg | SG | `newegg-sg`|
| Notebooksbilliger | DE |`notebooksbilliger`|
| Novatech | UK | `novatech`|
| Nvidia | US | `nvidia`|
| Nvidia API | | `nvidia-api`|
| Office Depot | US | `officedepot`|
| Ollo | IT | `ollo`|
| Otto | DE | `otto`|
| Overclockers | UK | `overclockers`|
| PBTech | AU | `pbtech`|
| PCByte | AU | `pcbyte`|
| PCCG | AU | `pccg`|
| PCComponentes | ES | `pccomponentes`|
| PCKing | DE | `pcking` |
| PlayStation | US | `playstation`|
| PNY | US | `pny`|
| Proshop | DE | `proshop-de`|
| Proshop | DK | `proshop-dk`|
| Rosman | AU | `rosman`|
| Rosman-Melb | AU | `rosman-melb`|
| Saturn | DE | `saturn`|
| Save On It | AU | `saveonit`|
| Scan | UK | `scan`|
| Scorptec | AU | `scorptec`|
| ShopTo | UK | `shopto`|
| Smyths Toys | UK | `smythstoys`|
| Smyths Toys | IE | `smythstoys-ie`|
| Spielegrotte | DE | `spielegrotte`|
| Storm Computers | AU | `storm-computer`|
| Target | US | `target`|
| Tesco | IE | `tesco-ie`|
| Toys R Us | US | `toysrus` |
| Umart | AU | `umart`|
| Unieuro | IT | `unieuro`|
| Very | UK | `very`|
| Vuugo | CA | `vuugo` |
| Walmart | US | `walmart`|
| Walmart | CA | `walmart-ca`|
| Wells Technology | AU | `wellstechnology`|
| Wipoid | ES | `wipoid`|
| Zotac | US | `zotac`|
| TopAchat | GR | `topachat`|
### Micro Center stores
Used with the `MICROCENTER_LOCATION` variable.
???+ note
Before using `web`, please review [this issue comment](https://github.com/jef/streetmerchant/issues/442#issuecomment-703297393).
| | | | |
|---|---|---|---|
| `brooklyn` | `brentwood` | `cambridge` | `chicago` |
| `columbus` | `dallas` | `denver` | `duluth` |
| `fairfax` | `flushing` | `houston` | `madison-heights` |
| `marietta` | `mayfield-heights` | `north-jersey` | `overland-park` |
| `parkville` | `rockville` | `sharonville` | `st-davids` |
| `st-louis-park` | `tustin` | `westbury` | `westmont` |
| `yonkers` |
## Supported brands and models
Used with the `SHOW_ONLY_BRANDS` and `SHOW_ONLY_MODELS` variables.
| Brand | Model |
|:---:|---|
| `amd` | `5600x`, `5800x`, `5900x`, `5950x`, `amd reference` |
| `asus` | `crosshair viii`, `dual`, `dual oc`, `ekwb`, `strix`, `strix oc`, `strix white`, `tuf`, `tuf oc` |
| `corsair` | `750 platinum`, `600 platinum` |
| `colorful` | `igame advanced oc`, `igame vulcan oc` |
| `evga` | `ftw3`, `ftw3 black`, `ftw3 ultra`, `ftw3 ultra hybrid`, `ftw3 ultra hydro copper`, `xc3`, `xc black`, `xc gaming`, `xc3 black`, `xc3 ultra`, `xc3 ultra hybrid` |
| `gainward` | `phantom gs`, `phoenix`, `phoenix gs`, `phoenix gs oc` |
| `gigabyte` | `aorus master`, `aorus xtreme`, `aorus xtreme waterforce`, `aorus xtreme waterforce wb`, `eagle`, `eagle oc`, `gaming`, `gaming oc`, `gaming oc pro`, `turbo`, `vision`, `vision oc` |
| `galax` | `sg`, `sg oc` |
| `inno3d` | `gaming x3`, `ichill x3`, `ichill x4`, `ichill frostbite`, `twin x2`, `twin x2 oc` |
| `kfa2` | `sg`, `sg oc` |
| `leadtek` | `hurricane` |
| `microsoft` | `xbox series x`, `xbox series s` |
| `msi` | `gaming x trio`, `suprim`, `suprim x`, `ventus 2x oc`, `ventus 3x`, `ventus 3x oc` |
| `nvidia` | `founders edition` |
| `palit` | `gamerock oc`, `gaming pro`, `gaming pro oc` |
| `pny` | `dual fan`, `xlr8 epic x`, `xlr8 revel`, `xlr8 uprising` |
| `sony` | `ps5 console`, `ps5 digital` |
| `xfx` | `merc`, `amd reference` |
| `zotac` | `amp holo`, `amp extreme holo`, `trinity`, `trinity oc`, `twin edge`, `twin edge oc`, `twin edge oc white` |
## Supported series
Used with the `SHOW_ONLY_SERIES` variable.
| Series | Value |
|:---:|:---:|
| AMD Ryzen 5600x | `ryzen5600` |
| AMD Ryzen 5800x | `ryzen5800` |
| AMD Ryzen 5900x | `ryzen5900` |
| AMD Ryzen 5950x | `ryzen5950` |
| AMD RX 6800 | `rx6800` |
| AMD RX 6800XT | `rx6800xt` |
| AMD RX 6900XT | `rx6900xt` |
| Nvidia RTX 3060 Ti | `3060ti` |
| Nvidia RTX 3070 | `3070` |
| Nvidia RTX 3080 | `3080` |
| Nvidia RTX 3090 | `3090` |
| Corsair SFX PSU | `sf` |
| Crosshair VIII | `darkhero` |
| Sony PS5 | `sonyps5c` |
| Sony PS5 Digital Edition | `sonyps5de` |
| Xbox Series S | `xboxss` |
| Xbox Series X | `xboxsx` |
## Supported countries
Used with the `COUNTRY` variable.
???+ attention
Used _only_ with `nvidia` and `nvidia-api`.
| Country | 3080 FE | 3090 FE | Test Card | Notes |
|:---:|:---:|:---:|:---:|:---:|
| `austria` | `✔` | `✔` | `✔` | |
| `belgium` | `✔` | `✔` | `✔` | |
| `canada` | `✔` | `✔` | `✔` | |
| `czechia` | `✔` | `✔` | `✔` | |
| `denmark` | `✔` | | `✔` | Missing RTX 3090 |
| `finland` | `✔` | | `✔` | Missing RTX 3090 |
| `france` | `✔` | `✔` | `✔` | |
| `germany` | `✔` | `✔` | `✔` | |
| `great_britain` | `✔` | `✔` | `✔` | |
| `ireland` | `✔` | `✔` | `✔` | |
| `italy` | `✔` | `✔` | `✔` | |
| `luxembourg` | `✔` | `✔` | `✔` | |
| `netherlands` | `✔` | `✔` | `✔` | |
| `norway` | `✔` | `✔` | `✔` | |
| `poland` | `✔` | `✔` | `✔` | |
| `portugal` | `✔` | | | RTX 3080 only |
| `spain` | `✔` | `✔` | `✔` | |
| `sweden` | `✔` | `✔` | `✔` | |
| `usa` | `✔` | `✔` | `✔` | |
+201
View File
@@ -0,0 +1,201 @@
# Notification
You can test your notification configuration by running `npm run test:notification`.
## Desktop
| Environment variable | Description |
|---|---|
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier). |
| `PLAY_SOUND` | Play this sound notification if a product is found. Relative path accepted, valid formats: wav, mp3, flac, E.g.: `path/to/notification.wav`, [free sounds available](https://notificationsounds.com/) |
| `SOUND_PLAYER` | Override the default sound player using the specified executable. |
???+ attention
If you're on Windows, you must have the proper library to run.
## Discord
| Environment variable | Description |
|:---:|---|
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify |
| `DISCORD_NOTIFY_GROUP_3060TI` | Discord group to notify on 3060 Ti stock |
| `DISCORD_NOTIFY_GROUP_3070` | Discord group to notify on 3070 stock |
| `DISCORD_NOTIFY_GROUP_3080` | Discord group to notify on 3080 stock |
| `DISCORD_NOTIFY_GROUP_3090` | Discord group to notify on 3090 stock |
| `DISCORD_NOTIFY_GROUP_RYZEN5600` | Discord group to notify on 5600X stock |
| `DISCORD_NOTIFY_GROUP_RYZEN5800` | Discord group to notify on 5800X stock |
| `DISCORD_NOTIFY_GROUP_RYZEN5900` | Discord group to notify on 5900X stock |
| `DISCORD_NOTIFY_GROUP_RYZEN5950` | Discord group to notify on 5950X stock |
| `DISCORD_NOTIFY_GROUP_DARKHERO` | Discord group to notify on Dark Hero stock |
| `DISCORD_NOTIFY_GROUP_CORSAIR_SF` | Discord group to notify on Corsair SF stock |
| `DISCORD_NOTIFY_GROUP_SONYPS5C` | Discord group to notify on Sony PS5 stock |
| `DISCORD_NOTIFY_GROUP_SONYPS5DE` | Discord group to notify on Sony PS5 Digital stock |
| `DISCORD_NOTIFY_GROUP_XBOXSX` | Discord group to notify on Xbox Series X stock |
| `DISCORD_NOTIFY_GROUP_XBOXSS` | Discord group to notify on Xbox Series S stock |
| `DISCORD_NOTIFY_GROUP_TEST` | Discord group to notify on test stock |
| `DISCORD_WEB_HOOK` | Discord Web Hook URL. Can be comma separated. Use whole webhook URL |
???+ note
All groups can be comma separated. `DISCORD_NOTIFY_GROUP` is always used if set.
- If you're using a role, please use `<@&2834729847239842>`
- If you're using a user, please use `<@2834729847239842>`
## Email and SMS
Default provider is Gmail. If you use a different email provider, you must provide SMTP settings.
| Environment variable | Description |
|:---:|---|
| `EMAIL_PASSWORD` | Email password. (See below for Gmail MFA users) |
| `EMAIL_TO` | Destination Email. Defaults to username if not set. Can be comma separated |
| `EMAIL_USERNAME` | Email address |
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS. E.g.: `att` or `att,verizon,google`, email configuration required. If multiple phone numbers are listed, enter a carrier for each phone number |
| `PHONE_NUMBER` | 10 digit phone number(s). E.g.: `1234567890` or `1234567890,0987654321,11112223333`, email configuration required |
| `SMTP_ADDRESS` | IP Address or FQDN of SMTP server |
| `SMTP_PORT` | TCP Port number on which the smtp server is listening for connections. Default: `25` |
???+ attention
If you use Gmail and have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
### Supported carriers
| Carrier | Environment variable |
|:---:|:---:|
| AT&T | `att` |
| AT&T Prepaid | `attgo` |
| Bell | `bell` |
| Fido | `fido` |
| Google | `google`|
| Koodo | `koodo` |
| Mint | `mint`|
| Rogers | `rogers` |
| Sprint | `sprint`|
| Telus | `telus`|
| T-Mobile | `tmobile`|
| Verizon | `verizon`|
| Virgin | `virgin`|
| Virgin (CA) | `virgin-ca`|
| Visible | `visible`|
## MQTT
| Environment variable | Description |
|:---:|---|
| `MQTT_BROKER_ADDRESS` | IP address or URL of MQTT Broker, e.g.: `192.168.1.xxx` or `broker.hivemq.com` |
| `MQTT_BROKER_PORT` | Network port of MQTT Broker. Default: `1883` |
| `MQTT_CLIENT_ID` | Unique Client ID (only if required by MQTT Broker), typically not required when only publishing alerts |
| `MQTT_PASSWORD` | MQTT password - only use with MQTT brokers on private networks, if required. Will not be sent over public networks for safety |
| `MQTT_QOS` | QoS level for published alerts to broker (https://www.npmjs.com/package/mqtt#about-qos). Default: `0`, Can be `0`, `1`, or `2` |
| `MQTT_TOPIC` | Topic to publish alerts to. Can include `%store%`, `%series%`, `%brand%`, `%model%` for dynamic topics. Default: `streetmerchant/alert`. E.g.: `nv-alert/%store%/%series%/%brand%/%model%/alert` |
| `MQTT_USERNAME` | MQTT username - (only if required by MQTT Broker) |
## PagerDuty
Obtained in PagerDuty - <Service you want to use> - Integrations
| Environment variable | Description |
|:---:|---|
| `PAGERDUTY_INTEGRATION_KEY` | PagerDuty Events API v2 Integration Key. |
| `PAGERDUTY_SEVERITY` | Severity of PagerDuty events |
## Philips Hue
Generate required keys using [instructions](https://developers.meethue.com/develop/get-started-2/). This will be used for both LAN and cloud access over the official Remote Hue API.
For cloud only usage, instructions to generate are located [here](https://developers.meethue.com/develop/hue-api/remote-authentication/).
> :point_right: Here's a [video demonstration](https://vimeo.com/476083242).
| Environment variable | Description |
|:---:|---|
| `PHILIPS_HUE_API_KEY` | Hue Bridge API Key |
| `PHILIPS_HUE_LAN_BRIDGE_IP` | LAN IP Address of your Hue Bridge. LAN only, e.g. `192.168.x.x` |
| `PHILIPS_HUE_LIGHT_IDS` | Light IDs. All lights if not supplied. Can be comma separated, e.g.: `1,2`. See Hue App -> About for IDs |
| `PHILIPS_HUE_LIGHT_COLOR` | Color in RGB Format. Nvidia green if not supplied. Can be comma separated, e.g.: `255,255,255` |
| `PHILIPS_HUE_LIGHT_PATTERN` | Lights will flash for 30 seconds if `blink` is given |
| `PHILIPS_HUE_CLOUD_ACCESS_TOKEN` | Cloud Access Token. Cloud only |
| `PHILIPS_HUE_CLOUD_REFRESH_TOKEN` | Cloud Refresh Token. Cloud only |
| `PHILIPS_HUE_CLOUD_CLIENT_ID` | Cloud Client ID. Cloud only |
| `PHILIPS_HUE_CLOUD_CLIENT_SECRET` | Cloud Client Secret. Cloud only |
## Pushbullet
Generate token at [pushbullet.com/#settings/account](https://pushbullet.com/#settings/account).
| Environment variable | Description |
|:---:|---|
| `PUSHBULLET` | API key |
## Pushover
Generate token at [pushover.net/apps/build](https://pushover.net/apps/build).
| Environment variable | Description |
|:---:|---|
| `PUSHOVER_EXPIRE` | How many seconds your notification will continue to be retried for (every `PUSHOVER_RETRY` seconds) |
| `PUSHOVER_RETRY` | How often (in seconds) the Pushover servers will send the same notification to the user |
| `PUSHOVER_PRIORITY` | Message priority |
| `PUSHOVER_TOKEN` | API token |
| `PUSHOVER_USER` | Username |
???+ note
`PUSHOVER_EXPIRE` and `PUSHOVER_RETRY` are only used when `PUSHOVER_PRIORITY="2"`
## Redis
| Environment variable | Description |
|:---:|---|
| `REDIS_URL` | Connection string in format (redis://[username]:[password]@[host][:port]/[database-id]) (redis://localhost:6379/1) |
## Slack
| Environment variable | Description |
|:---:|---|
| `SLACK_CHANNEL` | Channel for posting |
| `SLACK_TOKEN` | API token |
## Telegram
| Environment variable | Description |
|:---:|---|
| `TELEGRAM_ACCESS_TOKEN` | Access token |
| `TELEGRAM_CHAT_ID` | Chat ID. Can be comma separated, e.g.: `123456789,987654321` |
## Twilio
Token generation can be found at [twilio.com/console](https://twilio.com/console).
| Environment variable | Description |
|:---:|---|
| `TWILIO_ACCOUNT_SID` | Account SID |
| `TWILIO_AUTH_TOKEN` | Auth Token |
| `TWILIO_FROM_NUMBER` | Provided phone number to send messages from |
| `TWILIO_TO_NUMBER` | Mobile number to send SMS to |
???+ note
Include country codes in phone numbers. Example: `+4401234567890`
## Twitter
Generate all Twitter keys at [developer.twitter.com](https://developer.twitter.com).
| Environment variable | Description |
|:---:|---|
| `TWITTER_ACCESS_TOKEN_KEY` | Twitter Token Key |
| `TWITTER_ACCESS_TOKEN_SECRET` | Twitter Token Secret |
| `TWITTER_CONSUMER_KEY` | Twitter Consumer Key |
| `TWITTER_CONSUMER_SECRET` | Twitter Consumer Secret |
| `TWITTER_TWEET_TAGS` | List of hashtags to append to the tweet message, e.g.: `#nvidia #nvidiastock` |
## Twitch
Instructions on how to set up tokens can be found at [d-fischer.github.io/twitch-chat-client/docs/examples/basic-bot](https://d-fischer.github.io/twitch-chat-client/docs/examples/basic-bot).
| Environment variable | Description |
|:---:|---|
| `TWITCH_CLIENT_ID` | Twitch client ID |
| `TWITCH_CLIENT_SECRET`| Twitch client secret |
| `TWITCH_ACCESS_TOKEN` | Twitch access token |
| `TWITCH_REFRESH_TOKEN` | Twitch refresh token |
| `TWITCH_CHANNEL` | Twitch channel |
+20
View File
@@ -0,0 +1,20 @@
# Proxy
## Filename
Proxy configuration can be set either per store in a file called `storename.proxies` or globally in `global.proxies` in the streetmerchant root directory.
If both exist, the store specific file will take precedence.
## Format
The format is one proxy per line with the following structure:
`protocol://[user:password@]ip[:port]`
Supported protocols are `http` and `socks5`.
Valid examples include:
- `socks5://1.2.3.4:3180`
- `socks5://abcd:efgh@1.2.3.4:5678`
- `http://1.2.3.4:80`
- `http://abcd:efgh@1.2.3.4:8080`
+119
View File
@@ -0,0 +1,119 @@
# ** All configuration variables are optional **
# Copy this file and name it as `dotenv` (without backticks)
# Read https://jef.codes/streetmerchant/getting-started/#customization for help on customizing this file
########################################################################################################
ASCII_BANNER=
ASCII_COLOR=
AUTO_ADD_TO_CART=
BROWSER_TRUSTED=
COUNTRY=
DESKTOP_NOTIFICATIONS=
DISCORD_NOTIFY_GROUP=
DISCORD_NOTIFY_GROUP_3060TI=
DISCORD_NOTIFY_GROUP_3070=
DISCORD_NOTIFY_GROUP_3080=
DISCORD_NOTIFY_GROUP_3090=
DISCORD_NOTIFY_GROUP_CORSAIR_SF=
DISCORD_NOTIFY_GROUP_RX6800=
DISCORD_NOTIFY_GROUP_RX6800XT=
DISCORD_NOTIFY_GROUP_RX6900XT=
DISCORD_NOTIFY_GROUP_RYZEN5600=
DISCORD_NOTIFY_GROUP_RYZEN5800=
DISCORD_NOTIFY_GROUP_RYZEN5900=
DISCORD_NOTIFY_GROUP_RYZEN5950=
DISCORD_NOTIFY_GROUP_SONYPS5C=
DISCORD_NOTIFY_GROUP_SONYPS5DE=
DISCORD_NOTIFY_GROUP_XBOXSX=
DISCORD_NOTIFY_GROUP_XBOXSS=
DISCORD_NOTIFY_GROUP_TEST=
DISCORD_WEB_HOOK=
EMAIL_PASSWORD=
EMAIL_TO=
EMAIL_USERNAME=
HEADLESS=
IN_STOCK_WAIT_TIME=
LOG_LEVEL=
LOW_BANDWIDTH=
MAX_PRICE_SERIES_3060TI=
MAX_PRICE_SERIES_3070=
MAX_PRICE_SERIES_3080=
MAX_PRICE_SERIES_3090=
MAX_PRICE_SERIES_CORSAIR_SF=
MAX_PRICE_SERIES_RX6800=
MAX_PRICE_SERIES_RX6800XT=
MAX_PRICE_SERIES_RX6900XT=
MAX_PRICE_SERIES_RYZEN5600=
MAX_PRICE_SERIES_RYZEN5800=
MAX_PRICE_SERIES_RYZEN5900=
MAX_PRICE_SERIES_RYZEN5950=
MAX_PRICE_SERIES_SONYPS5C=
MAX_PRICE_SERIES_SONYPS5DE=
MAX_PRICE_SERIES_XBOXSS=
MAX_PRICE_SERIES_XBOXSX=
MAX_PRICE_SERIES_TEST=
MICROCENTER_LOCATION=
MQTT_BROKER_ADDRESS=
MQTT_BROKER_PORT=
MQTT_CLIENT_ID=
MQTT_PASSWORD=
MQTT_QOS=
MQTT_TOPIC=
MQTT_USERNAME=
NVIDIA_ADD_TO_CART_ATTEMPTS=
NVIDIA_SESSION_TTL=
OPEN_BROWSER=
PAGE_BACKOFF_MIN=
PAGE_BACKOFF_MAX=
PAGE_SLEEP_MIN=
PAGE_SLEEP_MAX=
PAGE_TIMEOUT=
PAGERDUTY_INTEGRATION_KEY=
PAGERDUTY_SEVERITY=
PHILIPS_HUE_API_KEY=
PHILIPS_HUE_CLOUD_ACCESS_TOKEN=
PHILIPS_HUE_CLOUD_CLIENT_ID=
PHILIPS_HUE_CLOUD_CLIENT_SECRET=
PHILIPS_HUE_CLOUD_REFRESH_TOKEN=
PHILIPS_HUE_LAN_BRIDGE_IP=
PHILIPS_HUE_LIGHT_COLOR=
PHILIPS_HUE_LIGHT_IDS=
PHILIPS_HUE_LIGHT_PATTERN=
PHONE_CARRIER=
PHONE_NUMBER=
PLAY_SOUND=
PROXY_ADDRESS=
PROXY_PROTOCOL=
PROXY_PORT=
PUSHBULLET=
PUSHOVER_EXPIRE=
PUSHOVER_RETRY=
PUSHOVER_TOKEN=
PUSHOVER_USER=
PUSHOVER_PRIORITY=
SCREENSHOT=
SHOW_ONLY_BRANDS=
SHOW_ONLY_MODELS=
SHOW_ONLY_SERIES=
SLACK_CHANNEL=
SLACK_TOKEN=
SMTP_ADDRESS=
SMTP_PORT=
STORES=
TELEGRAM_ACCESS_TOKEN=
TELEGRAM_CHAT_ID=
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_FROM_NUMBER=
TWILIO_TO_NUMBER=
TWITCH_ACCESS_TOKEN=
TWITCH_CHANNEL=
TWITCH_CLIENT_ID=
TWITCH_CLIENT_SECRET=
TWITCH_REFRESH_TOKEN=
TWITTER_ACCESS_TOKEN_KEY=
TWITTER_ACCESS_TOKEN_SECRET=
TWITTER_CONSUMER_KEY=
TWITTER_CONSUMER_SECRET=
TWITTER_TWEET_TAGS=
WEB_PORT=
Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

+93
View File
@@ -0,0 +1,93 @@
# Project information
site_name: streetmerchant
site_url: https://jef.codes/streetmerchant
site_author: Jef LeCompte
site_description: 🤖 The world's easiest, most powerful stock checker
# Repository
repo_name: jef/streetmerchant
repo_url: https://github.com/jef/streetmerchant
# Copyright
copyright: Copyright &copy; 2016 - 2020 Jef LeCompte
# Configuration
theme:
custom_dir: docs/overrides
favicon: https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-logo.png
features:
- search.suggest
font:
text: Roboto
code: Fira Code
icon:
repo: octicons/octoface-24
logo: assets/images/streetmerchant-logo.png
language: en
name: material
palette:
scheme: default
primary: indigo
accent: indigo
# Plugins
plugins:
- git-revision-date
- macros
- search
# Customization
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/jef
- icon: fontawesome/brands/twitter
link: https://twitter.com/hijxf
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/jeflecompte
extra_javascript:
- https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js
- javascripts/tables.js
# Extensions
markdown_extensions:
- admonition
- attr_list
- footnotes
- meta
- toc:
permalink: true
- pymdownx.caret
- pymdownx.critic
- pymdownx.details
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.highlight:
linenums: true
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tabbed
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
# Page tree
nav:
- Home: index.md
- Getting started: getting-started.md
- Reference:
- Application: reference/application.md
- Filter: reference/filter.md
- Notification: reference/notification.md
- Proxy: reference/proxy.md
- Help:
- General: help/general.md
- Troubleshoot: help/troubleshoot.md
- FAQ: faq.md
- Changelog: changelog.md
- About: about.md
+1 -1
View File
@@ -3,6 +3,6 @@
"ext": "ts", "ext": "ts",
"watch": [ "watch": [
"src/", "src/",
".env" "dotenv"
] ]
} }
+3615 -6631
View File
File diff suppressed because it is too large Load Diff
+60 -51
View File
@@ -1,79 +1,88 @@
{ {
"name": "nvidia-snatcher", "name": "streetmerchant",
"description": "🔮 For all your Nvidia needs", "description": "The world's easiest, most powerful stock checker",
"main": "src/index.ts", "main": "src/index.ts",
"scripts": { "scripts": {
"all": "npm run build && npm run lint", "all": "npm run compile && npm run lint && npm run test",
"build": "tsc", "fix": "gts fix",
"lint": "xo", "lint": "gts lint",
"lint:fix": "xo --fix", "clean": "gts clean",
"start": "npm run build && node build/index.js", "compile": "tsc",
"pretest": "npm run compile",
"posttest": "npm run lint",
"start": "npm run compile && node build/src/index.js",
"start:dev": "nodemon --config nodemon.json", "start:dev": "nodemon --config nodemon.json",
"test:notification": "npm run build && node build/__test__/notification-test.js" "start:production": "node build/src/index.js",
"test": "c8 mocha 'build/test/**/test-*.js' --exclude 'build/test/functional/**/test-*.js'",
"test:notification": "npm run compile && node build/test/functional/test-notification.js",
"test:notification:production": "node build/test/functional/test-notification.js"
},
"engines": {
"node": ">=12.0.0 <15.0.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/jef/nvidia-snatcher.git" "url": "git+https://github.com/jef/streetmerchant.git"
}, },
"keywords": [], "keywords": [],
"author": "jef", "author": "jef",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/jef/nvidia-snatcher/issues" "url": "https://github.com/jef/streetmerchant/issues"
}, },
"homepage": "https://github.com/jef/nvidia-snatcher#readme", "homepage": "https://github.com/jef/streetmerchant#readme",
"dependencies": { "dependencies": {
"@doridian/puppeteer-page-proxy": "^1.2.11",
"@jef/pushbullet": "^2.4.3", "@jef/pushbullet": "^2.4.3",
"@slack/web-api": "^5.13.0", "@slack/web-api": "^6.0.0",
"@types/random-useragent": "^0.3.0",
"@types/redis": "^2.8.28",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"cheerio": "^1.0.0-rc.3", "cheerio": "^1.0.0-rc.5",
"discord-webhook-node": "^1.1.8", "discord.js": "^12.5.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"messaging-api-telegram": "^1.0.1", "messaging-api-telegram": "^1.0.4",
"mqtt": "^4.2.3", "mqtt": "^4.2.6",
"node-notifier": "^8.0.0", "node-fetch": "^2.6.1",
"node-pagerduty": "^1.3.4", "node-hue-api": "^4.0.10",
"nodemailer": "^6.4.14", "node-notifier": "^9.0.0",
"open": "^7.3.0", "node-pagerduty": "^1.3.6",
"nodemailer": "^6.4.17",
"open": "^7.3.1",
"play-sound": "^1.1.3", "play-sound": "^1.1.3",
"puppeteer": "^5.4.1", "puppeteer": "^5.5.0",
"puppeteer-extra": "^3.1.15", "puppeteer-extra": "^3.1.16",
"puppeteer-extra-plugin-adblocker": "^2.11.7", "puppeteer-extra-plugin-adblocker": "^2.11.10",
"puppeteer-extra-plugin-block-resources": "^2.2.7", "puppeteer-extra-plugin-block-resources": "^2.2.8",
"puppeteer-extra-plugin-stealth": "^2.6.3", "puppeteer-extra-plugin-stealth": "^2.6.6",
"pushover-notifications": "^1.2.2", "pushover-notifications": "^1.2.2",
"twilio": "^3.50.0", "redis": "^3.0.2",
"twitch": "^4.2.7", "top-user-agents": "^1.0.19",
"twitch-auth": "^4.2.7", "twilio": "^3.55.0",
"twitch-chat-client": "^4.2.7", "twitch": "^4.4.0",
"twitch-auth": "^4.4.0",
"twitch-chat-client": "^4.4.0",
"twitter": "^1.7.1", "twitter": "^1.7.1",
"winston": "^3.3.3" "winston": "^3.3.3"
}, },
"devDependencies": { "devDependencies": {
"@types/async": "^3.2.3", "@types/async": "^3.2.5",
"@types/cheerio": "^0.22.22", "@types/cheerio": "^0.22.23",
"@types/node": "^14.14.6", "@types/mocha": "^8.2.0",
"@types/node": "^14.14.21",
"@types/node-fetch": "^2.5.8",
"@types/node-notifier": "^8.0.0", "@types/node-notifier": "^8.0.0",
"@types/nodemailer": "^6.4.0", "@types/nodemailer": "^6.4.0",
"@types/puppeteer": "^3.0.2", "@types/puppeteer": "^5.4.2",
"@types/sinon": "^9.0.10",
"@types/twitter": "^1.7.0", "@types/twitter": "^1.7.0",
"husky": "^4.3.0", "c8": "^7.4.0",
"nodemon": "^2.0.6", "gts": "^3.1.0",
"ts-node": "^9.0.0", "mocha": "^8.2.1",
"typescript": "^4.0.5", "nodemon": "^2.0.7",
"webpack": "^5.3.2", "sinon": "^9.2.3",
"xo": "^0.33.1" "ts-node": "^9.1.1",
}, "typescript": "^4.1.3",
"xo": { "webpack": "^5.14.0"
"rules": {
"sort-imports": "error",
"sort-keys": "error",
"sort-vars": "error"
}
},
"husky": {
"hooks": {
"pre-commit": "npm run all"
}
} }
} }
-26
View File
@@ -1,26 +0,0 @@
import {Link, Store} from '../store/model';
import {sendNotification} from '../notification';
const link: Link = {
brand: 'test:brand',
cartUrl: 'https://www.example.com/cartUrl',
model: 'test:model',
series: 'test:series',
url: 'https://www.example.com/url'
};
const store: Store = {
labels: {
inStock: {
container: 'test:container',
text: ['test:text']
}
},
links: [link],
name: 'test:name'
};
/**
* Send test email.
*/
sendNotification(link, store);
+14 -3
View File
@@ -2,12 +2,23 @@ import {Page} from 'puppeteer';
import {PuppeteerExtraPluginAdblocker} from 'puppeteer-extra-plugin-adblocker'; import {PuppeteerExtraPluginAdblocker} from 'puppeteer-extra-plugin-adblocker';
export const adBlocker = new PuppeteerExtraPluginAdblocker({ export const adBlocker = new PuppeteerExtraPluginAdblocker({
blockTrackers: true blockTrackers: true,
}); });
export async function enableBlockerInPage(page: Page) {
const blockerObject = await adBlocker.getBlocker();
if (blockerObject.isBlockingEnabled(page)) {
return;
}
await blockerObject.enableBlockingInPage(page);
}
export async function disableBlockerInPage(page: Page) { export async function disableBlockerInPage(page: Page) {
const blockerObject = await adBlocker.getBlocker(); const blockerObject = await adBlocker.getBlocker();
if (blockerObject.isBlockingEnabled(page)) { if (!blockerObject.isBlockingEnabled(page)) {
await blockerObject.disableBlockingInPage(page); return;
} }
await blockerObject.disableBlockingInPage(page);
} }
+23 -10
View File
@@ -1,12 +1,25 @@
import chalk from 'chalk'; import chalk from 'chalk';
import {readFileSync} from 'fs';
export const banner = chalk.green.bold(` const version = readFileSync('version.txt', 'utf8');
$$\\ $$\\ $$\\ $$\\ $$\\
\\__| $$ |\\__| $$ | $$ | export const banner = {
$$$$$$$\\ $$\\ $$\\ $$\\ $$$$$$$ |$$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\ asciiVersion: `
$$ __$$\\\\$$\\ $$ |$$ |$$ __$$ |$$ | \\____$$\\ $$$$$$\\ $$ _____|$$ __$$\\ \\____$$\\\\_$$ _| $$ _____|$$ __$$\\ $$ __$$\\ $$ __$$\\ ██████ ▄▄▄█████▓ ██▀███ ▓█████ ▓█████▄▄▄█████▓ ███▄ ▄███▓▓█████ ██▀███ ▄████▄ ██░ ██ ▄▄▄ ███▄ █ ▄▄▄█████▓
$$ | $$ |\\$$\\$$ / $$ |$$ / $$ |$$ | $$$$$$$ |\\______|\\$$$$$$\\ $$ | $$ | $$$$$$$ | $$ | $$ / $$ | $$ |$$$$$$$$ |$$ | \\__| ▒██ ▒ ▓ ██▒ ▓▒▓██ ▒ ██▒▓█ ▀ ▓█ ▀▓ ██▒ ▓▒▓██▒▀█▀ ██▒▓█ ▀ ▓██ ▒ ██▒▒██▀ ▀█ ▓██░ ██▒▒████▄ ██ ▀█ █ ▓ ██▒ ▓▒
$$ | $$ | \\$$$ / $$ |$$ | $$ |$$ |$$ __$$ | \\____$$\\ $$ | $$ |$$ __$$ | $$ |$$\\ $$ | $$ | $$ |$$ ____|$$ | ░ ▓██▄ ▒ ▓██░ ▒░▓██ ░▄█ ▒▒███ ▒███ ▒ ▓██░ ▒░▓██ ▓██░▒███ ▓██ ░▄█ ▒▒▓█ ▄ ▒██▀▀██░▒██ ▀█▄ ▓██ ▀█ ██▒▒ ▓██░ ▒░
$$ | $$ | \\$ / $$ |\\$$$$$$$ |$$ |\\$$$$$$$ | $$$$$$$ |$$ | $$ |\\$$$$$$$ | \\$$$$ |\\$$$$$$$\\ $$ | $$ |\\$$$$$$$\\ $$ | ▒ ██▒░ ▓██▓ ░ ▒██▀▀█▄ ▒▓█ ▄ ▒▓█ ▄░ ▓██▓ ░ ▒██ ▒██ ▒▓█ ▄ ▒██▀▀█▄ ▒▓▓▄ ▄██▒░▓█ ░██ ░██▄▄▄▄██ ▓██▒ ▐▌██▒░ ▓██▓ ░
\\__| \\__| \\_/ \\__| \\_______|\\__| \\_______| \\_______/ \\__| \\__| \\_______| \\____/ \\_______|\\__| \\__| \\_______|\\__| ▒██████▒▒ ▒██▒ ░ ░██▓ ▒██▒░▒████▒░▒████▒ ▒██▒ ░ ▒██▒ ░██▒░▒████▒░██▓ ▒██▒▒ ▓███▀ ░░▓█▒░██▓ ▓█ ▓██▒▒██░ ▓██░ ▒██▒ ░
`); ▒ ▒▓▒ ▒ ░ ▒ ░░ ░ ▒▓ ░▒▓░░░ ▒░ ░░░ ▒░ ░ ▒ ░░ ░ ▒░ ░ ░░░ ▒░ ░░ ▒▓ ░▒▓░░ ░▒ ▒ ░ ▒ ░░▒░▒ ▒▒ ▓▒█░░ ▒░ ▒ ▒ ▒ ░░
░ ░▒ ░ ░ ░ ░▒ ░ ▒░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░▒ ░ ▒░ ░ ▒ ▒ ░▒░ ░ ▒ ▒▒ ░░ ░░ ░ ▒░ ░
░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░░ ░ ░ ▒ ░ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
${version}`,
render(ascii: boolean, hexColor: string) {
return chalk
.hex(hexColor)
.bold(ascii ? this.asciiVersion : this.stringVersion);
},
stringVersion: `STREETMERCHANT
${version}`,
};
+233 -61
View File
@@ -1,11 +1,31 @@
import {existsSync, readFileSync} from 'fs';
import {banner} from './banner'; import {banner} from './banner';
import dotenv from 'dotenv';
console.info(banner);
import {config as config_} from 'dotenv';
import path from 'path'; import path from 'path';
import * as console from 'console';
config_({path: path.resolve(__dirname, '../.env')}); if (process.env.npm_config_conf) {
if (
existsSync(path.resolve(__dirname, '../../' + process.env.npm_config_conf))
) {
dotenv.config({
path: path.resolve(__dirname, '../../' + process.env.npm_config_conf),
});
} else {
dotenv.config({path: path.resolve(__dirname, '../../.env')});
}
} else if (existsSync(path.resolve(__dirname, '../../dotenv'))) {
dotenv.config({path: path.resolve(__dirname, '../../dotenv')});
} else {
dotenv.config({path: path.resolve(__dirname, '../../.env')});
}
console.info(
banner.render(
envOrBoolean(process.env.ASCII_BANNER, false),
envOrString(process.env.BANNER_COLOR, '#808080')
)
);
/** /**
* Returns environment variable, given array, or default array. * Returns environment variable, given array, or default array.
@@ -13,10 +33,16 @@ config_({path: path.resolve(__dirname, '../.env')});
* @param environment Interested environment variable. * @param environment Interested environment variable.
* @param array Default array. If not set, is `[]`. * @param array Default array. If not set, is `[]`.
*/ */
function envOrArray(environment: string | undefined, array?: string[]): string[] { function envOrArray(
return (environment ? ( environment: string | undefined,
environment.includes('\n') ? environment.split('\n') : environment.split(',') array?: string[]
) : (array ?? [])).map(s => s.trim()); ): string[] {
return (environment
? environment.includes('\n')
? environment.split('\n')
: environment.split(',')
: array ?? []
).map(s => s.trim());
} }
/** /**
@@ -25,8 +51,11 @@ function envOrArray(environment: string | undefined, array?: string[]): string[]
* @param environment Interested environment variable. * @param environment Interested environment variable.
* @param boolean Default boolean. If not set, is `true`. * @param boolean Default boolean. If not set, is `true`.
*/ */
function envOrBoolean(environment: string | undefined, boolean?: boolean): boolean { function envOrBoolean(
return environment ? environment === 'true' : (boolean ?? true); environment: string | undefined,
boolean?: boolean
): boolean {
return environment ? environment === 'true' : boolean ?? true;
} }
/** /**
@@ -36,7 +65,7 @@ function envOrBoolean(environment: string | undefined, boolean?: boolean): boole
* @param string Default string. If not set, is `''`. * @param string Default string. If not set, is `''`.
*/ */
function envOrString(environment: string | undefined, string?: string): string { function envOrString(environment: string | undefined, string?: string): string {
return environment ? environment : (string ?? ''); return environment ? environment : string ?? '';
} }
/** /**
@@ -46,13 +75,13 @@ function envOrString(environment: string | undefined, string?: string): string {
* @param number Default number. If not set, is `0`. * @param number Default number. If not set, is `0`.
*/ */
function envOrNumber(environment: string | undefined, number?: number): number { function envOrNumber(environment: string | undefined, number?: number): number {
return environment ? Number(environment) : (number ?? 0); return environment ? Number(environment) : number ?? 0;
} }
/** /**
* Returns environment variable, given number, or default number, * Returns environment variable, given number, or default number,
* while handling .env input errors for a Min/Max pair. * while handling dotenv input errors for a Min/Max pair.
* .env errors handled: * dotenv errors handled:
* - Min/Max swapped (Min larger than Max, Max smaller than Min) * - Min/Max swapped (Min larger than Max, Max smaller than Min)
* - Min larger than default Max when no Max defined * - Min larger than default Max when no Max defined
* - Max smaller than default Min when no Min defined * - Max smaller than default Min when no Min defined
@@ -61,14 +90,24 @@ function envOrNumber(environment: string | undefined, number?: number): number {
* @param environmentMax Max environment variable of Min/Max pair. * @param environmentMax Max environment variable of Min/Max pair.
* @param number Default number. If not set, is `0`. * @param number Default number. If not set, is `0`.
*/ */
function envOrNumberMin(environmentMin: string | undefined, environmentMax: string | undefined, number?: number) { function envOrNumberMin(
environmentMin: string | undefined,
environmentMax: string | undefined,
number?: number
) {
if (environmentMin || environmentMax) { if (environmentMin || environmentMax) {
if (environmentMin && environmentMax) { if (environmentMin && environmentMax) {
return Number(Number(environmentMin) < Number(environmentMax) ? environmentMin : environmentMax); return Number(
Number(environmentMin) < Number(environmentMax)
? environmentMin
: environmentMax
);
} }
if (environmentMax) { if (environmentMax) {
return Number(environmentMax) < (number ?? 0) ? Number(environmentMax) : (number ?? 0); return Number(environmentMax) < (number ?? 0)
? Number(environmentMax)
: number ?? 0;
} }
if (environmentMin) { if (environmentMin) {
@@ -81,8 +120,8 @@ function envOrNumberMin(environmentMin: string | undefined, environmentMax: stri
/** /**
* Returns environment variable, given number, or default number, * Returns environment variable, given number, or default number,
* while handling .env input errors for a Min/Max pair. * while handling dotenv input errors for a Min/Max pair.
* .env errors handled: * dotenv errors handled:
* - Min/Max swapped (Min larger than Max, Max smaller than Min) * - Min/Max swapped (Min larger than Max, Max smaller than Min)
* - Min larger than default Max when no Max defined * - Min larger than default Max when no Max defined
* - Max smaller than default Min when no Min defined * - Max smaller than default Min when no Min defined
@@ -91,14 +130,24 @@ function envOrNumberMin(environmentMin: string | undefined, environmentMax: stri
* @param environmentMax Max environment variable of Min/Max pair. * @param environmentMax Max environment variable of Min/Max pair.
* @param number Default number. If not set, is `0`. * @param number Default number. If not set, is `0`.
*/ */
function envOrNumberMax(environmentMin: string | undefined, environmentMax: string | undefined, number?: number) { function envOrNumberMax(
environmentMin: string | undefined,
environmentMax: string | undefined,
number?: number
) {
if (environmentMin || environmentMax) { if (environmentMin || environmentMax) {
if (environmentMin && environmentMax) { if (environmentMin && environmentMax) {
return Number(Number(environmentMin) < Number(environmentMax) ? environmentMax : environmentMax); return Number(
Number(environmentMin) < Number(environmentMax)
? environmentMax
: environmentMax
);
} }
if (environmentMin) { if (environmentMin) {
return Number(environmentMin) > (number ?? 0) ? Number(environmentMin) : (number ?? 0); return Number(environmentMin) > (number ?? 0)
? Number(environmentMin)
: number ?? 0;
} }
if (environmentMax) { if (environmentMax) {
@@ -109,19 +158,48 @@ function envOrNumberMax(environmentMin: string | undefined, environmentMax: stri
return number ?? 0; return number ?? 0;
} }
function loadProxyList(filename: string): string[] {
try {
return readFileSync(`${filename}.proxies`)
.toString()
.trim()
.split('\n')
.map(x => x.trim());
} catch {
return [];
}
}
const browser = { const browser = {
isHeadless: envOrBoolean(process.env.HEADLESS), isHeadless: envOrBoolean(process.env.HEADLESS),
isIncognito: envOrBoolean(process.env.INCOGNITO, false), isIncognito: envOrBoolean(process.env.INCOGNITO, false),
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false), isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
lowBandwidth: envOrBoolean(process.env.LOW_BANDWIDTH, false), lowBandwidth: envOrBoolean(process.env.LOW_BANDWIDTH, false),
maxBackoff: envOrNumberMax(process.env.PAGE_BACKOFF_MIN, process.env.PAGE_BACKOFF_MAX, 3600000), maxBackoff: envOrNumberMax(
maxSleep: envOrNumberMax(process.env.PAGE_SLEEP_MIN, process.env.PAGE_SLEEP_MAX, 10000), process.env.PAGE_BACKOFF_MIN,
minBackoff: envOrNumberMin(process.env.PAGE_BACKOFF_MIN, process.env.PAGE_BACKOFF_MAX, 10000), process.env.PAGE_BACKOFF_MAX,
minSleep: envOrNumberMin(process.env.PAGE_SLEEP_MIN, process.env.PAGE_SLEEP_MAX, 5000), 3600000
open: envOrBoolean(process.env.OPEN_BROWSER) ),
maxSleep: envOrNumberMax(
process.env.PAGE_SLEEP_MIN,
process.env.PAGE_SLEEP_MAX,
10000
),
minBackoff: envOrNumberMin(
process.env.PAGE_BACKOFF_MIN,
process.env.PAGE_BACKOFF_MAX,
10000
),
minSleep: envOrNumberMin(
process.env.PAGE_SLEEP_MIN,
process.env.PAGE_SLEEP_MAX,
5000
),
open: envOrBoolean(process.env.OPEN_BROWSER),
userAgent: '',
}; };
const docker = envOrBoolean(process.env.DOCKER); const docker = envOrBoolean(process.env.DOCKER, false);
const logLevel = envOrString(process.env.LOG_LEVEL, 'info'); const logLevel = envOrString(process.env.LOG_LEVEL, 'info');
@@ -129,14 +207,38 @@ const notifications = {
desktop: process.env.DESKTOP_NOTIFICATIONS === 'true', desktop: process.env.DESKTOP_NOTIFICATIONS === 'true',
discord: { discord: {
notifyGroup: envOrArray(process.env.DISCORD_NOTIFY_GROUP), notifyGroup: envOrArray(process.env.DISCORD_NOTIFY_GROUP),
webHookUrl: envOrArray(process.env.DISCORD_WEB_HOOK) notifyGroupSeries: {
'3060ti': envOrArray(process.env.DISCORD_NOTIFY_GROUP_3060TI),
3070: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3070),
3080: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3080),
3090: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3090),
'captcha-deterrent': [],
darkhero: envOrArray(process.env.DISCORD_NOTIFY_GROUP_DARKHERO),
rx6800: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800),
rx6800xt: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800XT),
rx6900xt: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6900XT),
ryzen5600: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5600),
ryzen5800: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5800),
ryzen5900: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5900),
ryzen5950: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5950),
sf: envOrArray(process.env.DISCORD_NOTIFY_GROUP_CORSAIR_SF),
sonyps5c: envOrArray(process.env.DISCORD_NOTIFY_GROUP_SONYPS5C),
sonyps5de: envOrArray(process.env.DISCORD_NOTIFY_GROUP_SONYPS5DE),
'test:series': envOrArray(process.env.DISCORD_NOTIFY_GROUP_TEST),
xboxss: envOrArray(process.env.DISCORD_NOTIFY_GROUP_XBOXSS),
xboxsx: envOrArray(process.env.DISCORD_NOTIFY_GROUP_XBOXSX),
},
webhooks: envOrArray(process.env.DISCORD_WEB_HOOK),
}, },
email: { email: {
password: envOrString(process.env.EMAIL_PASSWORD), password: envOrString(process.env.EMAIL_PASSWORD),
smtpAddress: envOrString(process.env.SMTP_ADDRESS), smtpAddress: envOrString(process.env.SMTP_ADDRESS),
smtpPort: envOrNumber(process.env.SMTP_PORT, 25), smtpPort: envOrNumber(process.env.SMTP_PORT, 25),
to: envOrString(process.env.EMAIL_TO, envOrString(process.env.EMAIL_USERNAME)), to: envOrString(
username: envOrString(process.env.EMAIL_USERNAME) process.env.EMAIL_TO,
envOrString(process.env.EMAIL_USERNAME)
),
username: envOrString(process.env.EMAIL_USERNAME),
}, },
mqtt: { mqtt: {
broker: envOrString(process.env.MQTT_BROKER_ADDRESS), broker: envOrString(process.env.MQTT_BROKER_ADDRESS),
@@ -144,12 +246,24 @@ const notifications = {
password: envOrString(process.env.MQTT_PASSWORD), password: envOrString(process.env.MQTT_PASSWORD),
port: envOrNumber(process.env.MQTT_BROKER_PORT, 1883), port: envOrNumber(process.env.MQTT_BROKER_PORT, 1883),
qos: envOrNumber(process.env.MQTT_QOS, 0), qos: envOrNumber(process.env.MQTT_QOS, 0),
topic: envOrString(process.env.MQTT_TOPIC, 'nvidia-snatcher/alert'), topic: envOrString(process.env.MQTT_TOPIC, 'streetmerchant/alert'),
username: envOrString(process.env.MQTT_USERNAME) username: envOrString(process.env.MQTT_USERNAME),
}, },
pagerduty: { pagerduty: {
integrationKey: envOrString(process.env.PAGERDUTY_INTEGRATION_KEY), integrationKey: envOrString(process.env.PAGERDUTY_INTEGRATION_KEY),
severity: envOrString(process.env.PAGERDUTY_SEVERITY, 'info') severity: envOrString(process.env.PAGERDUTY_SEVERITY, 'info'),
},
philips_hue: {
accessToken: envOrString(process.env.PHILIPS_HUE_CLOUD_ACCESS_TOKEN),
apiKey: envOrString(process.env.PHILIPS_HUE_API_KEY),
bridgeIp: envOrString(process.env.PHILIPS_HUE_LAN_BRIDGE_IP),
clientId: envOrString(process.env.PHILIPS_HUE_CLOUD_CLIENT_ID),
clientSecret: envOrString(process.env.PHILIPS_HUE_CLOUD_CLIENT_SECRET),
lightColor: envOrString(process.env.PHILIPS_HUE_LIGHT_COLOR),
lightIds: envOrString(process.env.PHILIPS_HUE_LIGHT_IDS),
lightPattern: envOrString(process.env.PHILIPS_HUE_LIGHT_PATTERN),
refreshToken: envOrString(process.env.PHILIPS_HUE_CLOUD_REFRESH_TOKEN),
remoteApiUsername: envOrString(process.env.PHILIPS_HUE_API_KEY),
}, },
phone: { phone: {
availableCarriers: new Map([ availableCarriers: new Map([
@@ -166,51 +280,58 @@ const notifications = {
['tmobile', 'tmomail.net'], ['tmobile', 'tmomail.net'],
['verizon', 'vtext.com'], ['verizon', 'vtext.com'],
['virgin', 'vmobl.com'], ['virgin', 'vmobl.com'],
['virgin-ca', 'vmobile.ca'] ['virgin-ca', 'vmobile.ca'],
['visible', 'vtext.com'],
]), ]),
carrier: envOrString(process.env.PHONE_CARRIER), carrier: envOrArray(process.env.PHONE_CARRIER),
number: envOrString(process.env.PHONE_NUMBER) number: envOrArray(process.env.PHONE_NUMBER),
}, },
playSound: envOrString(process.env.PLAY_SOUND), playSound: envOrString(process.env.PLAY_SOUND),
pushbullet: envOrString(process.env.PUSHBULLET), pushbullet: envOrString(process.env.PUSHBULLET),
pushover: { pushover: {
expire: envOrNumber(process.env.PUSHOVER_EXPIRE),
priority: envOrNumber(process.env.PUSHOVER_PRIORITY), priority: envOrNumber(process.env.PUSHOVER_PRIORITY),
retry: envOrNumber(process.env.PUSHOVER_RETRY),
token: envOrString(process.env.PUSHOVER_TOKEN), token: envOrString(process.env.PUSHOVER_TOKEN),
username: envOrString(process.env.PUSHOVER_USER) username: envOrString(process.env.PUSHOVER_USER),
},
redis: {
url: envOrString(process.env.REDIS_URL),
}, },
slack: { slack: {
channel: envOrString(process.env.SLACK_CHANNEL), channel: envOrString(process.env.SLACK_CHANNEL),
token: envOrString(process.env.SLACK_TOKEN) token: envOrString(process.env.SLACK_TOKEN),
}, },
soundPlayer: envOrString(process.env.SOUND_PLAYER),
telegram: { telegram: {
accessToken: envOrString(process.env.TELEGRAM_ACCESS_TOKEN), accessToken: envOrString(process.env.TELEGRAM_ACCESS_TOKEN),
chatId: envOrArray(process.env.TELEGRAM_CHAT_ID) chatId: envOrArray(process.env.TELEGRAM_CHAT_ID),
}, },
twilio: { twilio: {
accountSid: envOrString(process.env.TWILIO_ACCOUNT_SID), accountSid: envOrString(process.env.TWILIO_ACCOUNT_SID),
authToken: envOrString(process.env.TWILIO_AUTH_TOKEN), authToken: envOrString(process.env.TWILIO_AUTH_TOKEN),
from: envOrString(process.env.TWILIO_FROM_NUMBER), from: envOrString(process.env.TWILIO_FROM_NUMBER),
to: envOrString(process.env.TWILIO_TO_NUMBER) to: envOrString(process.env.TWILIO_TO_NUMBER),
}, },
twitch: { twitch: {
accessToken: envOrString(process.env.TWITCH_ACCESS_TOKEN), accessToken: envOrString(process.env.TWITCH_ACCESS_TOKEN),
channel: envOrString(process.env.TWITCH_CHANNEL), channel: envOrString(process.env.TWITCH_CHANNEL),
clientId: envOrString(process.env.TWITCH_CLIENT_ID), clientId: envOrString(process.env.TWITCH_CLIENT_ID),
clientSecret: envOrString(process.env.TWITCH_CLIENT_SECRET), clientSecret: envOrString(process.env.TWITCH_CLIENT_SECRET),
refreshToken: envOrString(process.env.TWITCH_REFRESH_TOKEN) refreshToken: envOrString(process.env.TWITCH_REFRESH_TOKEN),
}, },
twitter: { twitter: {
accessTokenKey: envOrString(process.env.TWITTER_ACCESS_TOKEN_KEY), accessTokenKey: envOrString(process.env.TWITTER_ACCESS_TOKEN_KEY),
accessTokenSecret: envOrString(process.env.TWITTER_ACCESS_TOKEN_SECRET), accessTokenSecret: envOrString(process.env.TWITTER_ACCESS_TOKEN_SECRET),
consumerKey: envOrString(process.env.TWITTER_CONSUMER_KEY), consumerKey: envOrString(process.env.TWITTER_CONSUMER_KEY),
consumerSecret: envOrString(process.env.TWITTER_CONSUMER_SECRET), consumerSecret: envOrString(process.env.TWITTER_CONSUMER_SECRET),
tweetTags: envOrString(process.env.TWITTER_TWEET_TAGS) tweetTags: envOrString(process.env.TWITTER_TWEET_TAGS),
} },
}; };
const nvidia = { const nvidia = {
addToCardAttempts: envOrNumber(process.env.NVIDIA_ADD_TO_CART_ATTEMPTS, 10), addToCardAttempts: envOrNumber(process.env.NVIDIA_ADD_TO_CART_ATTEMPTS, 10),
sessionTtl: envOrNumber(process.env.NVIDIA_SESSION_TTL, 60000) sessionTtl: envOrNumber(process.env.NVIDIA_SESSION_TTL, 60000),
}; };
const page = { const page = {
@@ -218,28 +339,47 @@ const page = {
inStockWaitTime: envOrNumber(process.env.IN_STOCK_WAIT_TIME), inStockWaitTime: envOrNumber(process.env.IN_STOCK_WAIT_TIME),
screenshot: envOrBoolean(process.env.SCREENSHOT), screenshot: envOrBoolean(process.env.SCREENSHOT),
timeout: envOrNumber(process.env.PAGE_TIMEOUT, 30000), timeout: envOrNumber(process.env.PAGE_TIMEOUT, 30000),
userAgents: envOrArray(process.env.USER_AGENT, ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36']), width: 1920,
width: 1920
}; };
const proxy = { const proxy = {
address: envOrString(process.env.PROXY_ADDRESS), address: envOrString(process.env.PROXY_ADDRESS),
port: envOrNumber(process.env.PROXY_PORT, 80) port: envOrNumber(process.env.PROXY_PORT, 80),
protocol: envOrString(process.env.PROXY_PROTOCOL, 'http'),
}; };
// Check for deprecated configuration values // Check for deprecated configuration values
if (process.env.MAX_PRICE) { if (process.env.MAX_PRICE) {
console.warn(' MAX_PRICE is deprecated, please use MAX_PRICE_SERIES_{{series}}'); console.warn(
' MAX_PRICE is deprecated, please use MAX_PRICE_SERIES_{{series}}'
);
} }
const store = { const store = {
autoAddToCart: envOrBoolean(process.env.AUTO_ADD_TO_CART, true),
country: envOrString(process.env.COUNTRY, 'usa'), country: envOrString(process.env.COUNTRY, 'usa'),
maxPrice: { maxPrice: {
series: { series: {
'3060ti': envOrNumber(process.env.MAX_PRICE_SERIES_3060TI),
3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070), 3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070),
3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080), 3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080),
3090: envOrNumber(process.env.MAX_PRICE_SERIES_3090) 3090: envOrNumber(process.env.MAX_PRICE_SERIES_3090),
} 'captcha-deterrent': 0,
darkhero: envOrNumber(process.env.MAX_PRICE_SERIES_DARKHERO),
rx6800: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800),
rx6800xt: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800XT),
rx6900xt: envOrNumber(process.env.MAX_PRICE_SERIES_RX6900XT),
ryzen5600: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5600),
ryzen5800: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5800),
ryzen5900: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5900),
ryzen5950: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5950),
sf: envOrNumber(process.env.MAX_PRICE_SERIES_CORSAIR_SF),
sonyps5c: envOrNumber(process.env.MAX_PRICE_SERIES_SONYPS5C),
sonyps5de: envOrNumber(process.env.MAX_PRICE_SERIES_SONYPS5DE),
'test:series': envOrNumber(process.env.MAX_PRICE_SERIES_TEST),
xboxss: envOrNumber(process.env.MAX_PRICE_SERIES_XBOXSS),
xboxsx: envOrNumber(process.env.MAX_PRICE_SERIES_XBOXSX),
},
}, },
microCenterLocation: envOrArray(process.env.MICROCENTER_LOCATION, ['web']), microCenterLocation: envOrArray(process.env.MICROCENTER_LOCATION, ['web']),
showOnlyBrands: envOrArray(process.env.SHOW_ONLY_BRANDS), showOnlyBrands: envOrArray(process.env.SHOW_ONLY_BRANDS),
@@ -247,23 +387,55 @@ const store = {
const [name, series] = entry.match(/[^:]+/g) ?? []; const [name, series] = entry.match(/[^:]+/g) ?? [];
return { return {
name: envOrString(name), name: envOrString(name),
series: envOrString(series) series: envOrString(series),
}; };
}), }),
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, ['3070', '3080', '3090']), showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, [
stores: envOrArray(process.env.STORES, ['nvidia']).map(entry => { '3060ti',
'3070',
'3080',
'3090',
'rx6800',
'rx6800xt',
'rx6900xt',
'ryzen5600',
'ryzen5800',
'ryzen5900',
'ryzen5950',
'sonyps5c',
'sonyps5de',
'xboxss',
'xboxsx',
]),
stores: envOrArray(process.env.STORES, ['amazon', 'bestbuy']).map(entry => {
const [name, minPageSleep, maxPageSleep] = entry.match(/[^:]+/g) ?? []; const [name, minPageSleep, maxPageSleep] = entry.match(/[^:]+/g) ?? [];
let proxyList = loadProxyList(name);
if (proxyList.length === 0) {
proxyList = loadProxyList('global');
}
return { return {
maxPageSleep: envOrNumberMax(minPageSleep, maxPageSleep, browser.maxSleep), maxPageSleep: envOrNumberMax(
minPageSleep: envOrNumberMin(minPageSleep, maxPageSleep, browser.minSleep), minPageSleep,
name: envOrString(name) maxPageSleep,
browser.maxSleep
),
minPageSleep: envOrNumberMin(
minPageSleep,
maxPageSleep,
browser.minSleep
),
name: envOrString(name),
proxyList,
}; };
}) }),
}; };
export const defaultStoreData = { export const defaultStoreData = {
maxPageSleep: browser.maxSleep, maxPageSleep: browser.maxSleep,
minPageSleep: browser.minSleep minPageSleep: browser.minSleep,
}; };
export const config = { export const config = {
@@ -274,7 +446,7 @@ export const config = {
nvidia, nvidia,
page, page,
proxy, proxy,
store store,
}; };
export function setConfig(newConfig: any) { export function setConfig(newConfig: any) {
+25 -19
View File
@@ -1,23 +1,15 @@
import {startAPIServer, stopAPIServer} from './web'; import * as Process from 'process';
import {config} from './config'; // Needs to be loaded first
import {startAPIServer, stopAPIServer} from './web'; // eslint-disable-line sort-imports
import {Browser} from 'puppeteer'; import {Browser} from 'puppeteer';
import {adBlocker} from './adblocker';
import {config} from './config';
import {getSleepTime} from './util'; import {getSleepTime} from './util';
import {logger} from './logger'; import {logger} from './logger';
import puppeteer from 'puppeteer-extra'; import puppeteer from 'puppeteer-extra';
import resourceBlock from 'puppeteer-extra-plugin-block-resources';
import stealthPlugin from 'puppeteer-extra-plugin-stealth'; import stealthPlugin from 'puppeteer-extra-plugin-stealth';
import {storeList} from './store/model'; import {storeList} from './store/model';
import {tryLookupAndLoop} from './store'; import {tryLookupAndLoop} from './store';
puppeteer.use(stealthPlugin()); puppeteer.use(stealthPlugin());
if (config.browser.lowBandwidth) {
puppeteer.use(resourceBlock({
blockedTypes: new Set(['image', 'font'] as const)
}));
} else {
puppeteer.use(adBlocker);
}
let browser: Browser | undefined; let browser: Browser | undefined;
@@ -35,26 +27,38 @@ async function main() {
} }
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips
// https://stackoverflow.com/questions/48230901/docker-alpine-with-node-js-and-chromium-headless-puppeter-failed-to-launch-c
if (config.docker) { if (config.docker) {
args.push('--disable-dev-shm-usage'); args.push('--disable-dev-shm-usage');
args.push('--no-sandbox');
args.push('--disable-setuid-sandbox');
args.push('--headless');
args.push('--disable-gpu');
} }
// Add the address of the proxy server if defined // Add the address of the proxy server if defined
if (config.proxy.address) { if (config.proxy.address) {
args.push(`--proxy-server=http://${config.proxy.address}:${config.proxy.port}`); args.push(
`--proxy-server=${config.proxy.protocol}://${config.proxy.address}:${config.proxy.port}`
);
}
if (args.length > 0) {
logger.info(' puppeteer config: ', args);
} }
await stop(); await stop();
browser = await puppeteer.launch({ browser = await puppeteer.launch({
args, args,
defaultViewport: { defaultViewport: {
height: config.page.height, height: config.page.height,
width: config.page.width width: config.page.width,
}, },
headless: config.browser.isHeadless headless: config.browser.isHeadless,
}); });
config.browser.userAgent = await browser.userAgent();
for (const store of storeList.values()) { for (const store of storeList.values()) {
logger.debug('store links', {meta: {links: store.links}}); logger.debug('store links', {meta: {links: store.links}});
if (store.setupAction !== undefined) { if (store.setupAction !== undefined) {
@@ -80,8 +84,7 @@ async function stop() {
async function stopAndExit() { async function stopAndExit() {
await stop(); await stop();
// eslint-disable-next-line unicorn/no-process-exit Process.exit(0);
process.exit(0);
} }
/** /**
@@ -90,8 +93,11 @@ async function stopAndExit() {
async function loopMain() { async function loopMain() {
try { try {
await main(); await main();
} catch (error) { } catch (error: unknown) {
logger.error('✖ something bad happened, resetting nvidia-snatcher in 5 seconds', error); logger.error(
'✖ something bad happened, resetting streetmerchant in 5 seconds',
error
);
setTimeout(loopMain, 5000); setTimeout(loopMain, 5000);
} }
} }
+149 -30
View File
@@ -6,58 +6,107 @@ import winston from 'winston';
const prettyJson = winston.format.printf(info => { const prettyJson = winston.format.printf(info => {
const timestamp = new Date().toLocaleTimeString(); const timestamp = new Date().toLocaleTimeString();
if (typeof info.message === 'object') { let out = `${chalk.grey(`[${timestamp}]`)} ${info.level} ${chalk.grey(
info.message = JSON.stringify(info.message, null, 4); '::'
)} ${info.message}`;
if (Object.keys(info.metadata).length > 0) {
out = `${out} ${chalk.magenta(JSON.stringify(info.metadata, null, 2))}`;
} }
if (info.meta) { return out;
return chalk.grey(`[${timestamp}]`) + ` ${info.level} ` + chalk.grey('::') + ` ${info.message} ${chalk.magenta(JSON.stringify(info.meta, null, 2))}`;
}
return chalk.grey(`[${timestamp}]`) + ` ${info.level} ` + chalk.grey('::') + ` ${info.message}`;
}); });
export const logger = winston.createLogger({ export const logger = winston.createLogger({
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize(), winston.format.colorize(),
winston.format.prettyPrint(), winston.format.metadata({
winston.format.splat(), fillExcept: ['level', 'message', 'timestamp'],
winston.format.simple(), }),
prettyJson prettyJson
), ),
level: config.logLevel, level: config.logLevel,
transports: [new winston.transports.Console({})] transports: [new winston.transports.Console({})],
}); });
export const Print = { export const Print = {
backoff(link: Link, store: Store, parameters: {delay: number; statusCode: number}, color?: boolean): string { backoff(
link: Link,
store: Store,
parameters: {delay: number; statusCode: number},
color?: boolean
): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow(`BACKOFF DELAY status=${parameters.statusCode} delay=${parameters.delay}`); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow(
`BACKOFF DELAY status=${parameters.statusCode} delay=${parameters.delay}`
)
);
} }
return `${buildProductString(link, store)} :: BACKOFF DELAY status=${parameters.statusCode} delay=${parameters.delay}`; return `${buildProductString(link, store)} :: BACKOFF DELAY status=${
parameters.statusCode
} delay=${parameters.delay}`;
}, },
badStatusCode(link: Link, store: Store, statusCode: number, color?: boolean): string { badStatusCode(
link: Link,
store: Store,
statusCode: number,
color?: boolean
): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow(`STATUS CODE ERROR ${statusCode}`); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow(`STATUS CODE ERROR ${statusCode}`)
);
} }
return `${buildProductString(link, store)} :: STATUS CODE ERROR ${statusCode}`; return `${buildProductString(
link,
store
)} :: STATUS CODE ERROR ${statusCode}`;
}, },
bannedSeller(link: Link, store: Store, color?: boolean): string { bannedSeller(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('BANNED SELLER'); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('BANNED SELLER')
);
} }
return `${buildProductString(link, store)} :: BANNED SELLER`; return `${buildProductString(link, store)} :: BANNED SELLER`;
}, },
captcha(link: Link, store: Store, color?: boolean): string { captcha(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('CAPTCHA'); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('CAPTCHA')
);
} }
return `${buildProductString(link, store)} :: CAPTCHA`; return `${buildProductString(link, store)} :: CAPTCHA`;
}, },
cloudflare(link: Link, store: Store, color?: boolean): string {
if (color) {
return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('CLOUDFLARE, WAITING')
);
}
return `${buildProductString(link, store)} :: CLOUDFLARE, WAITING`;
},
inStock(link: Link, store: Store, color?: boolean, sms?: boolean): string { inStock(link: Link, store: Store, color?: boolean, sms?: boolean): string {
const productString = `${buildProductString(link, store)} :: IN STOCK`; const productString = `${buildProductString(link, store)} :: IN STOCK`;
@@ -73,49 +122,116 @@ export const Print = {
}, },
inStockWaiting(link: Link, store: Store, color?: boolean): string { inStockWaiting(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return ' ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('IN STOCK, WAITING'); return (
' ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('IN STOCK, WAITING')
);
} }
return ` ${buildProductString(link, store)} :: IN STOCK, WAITING`; return ` ${buildProductString(link, store)} :: IN STOCK, WAITING`;
}, },
maxPrice(link: Link, store: Store, price: number, maxPrice: number, color?: boolean): string { maxPrice(
link: Link,
store: Store,
maxPrice: number,
color?: boolean
): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow(`PRICE ${price} EXCEEDS LIMIT ${maxPrice}`); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow(`PRICE ${link.price ?? ''} EXCEEDS LIMIT ${maxPrice}`)
);
} }
return `${buildProductString(link, store)} :: PRICE ${price} EXCEEDS LIMIT ${maxPrice}`; return `${buildProductString(link, store)} :: PRICE ${
link.price ?? ''
} EXCEEDS LIMIT ${maxPrice}`;
}, },
message(message: string, topic: string, store: Store, color?: boolean): string { message(
message: string,
topic: string,
store: Store,
color?: boolean
): string {
if (color) { if (color) {
return '✖ ' + buildSetupString(topic, store, true) + ' :: ' + chalk.yellow(message); return (
'✖ ' +
buildSetupString(topic, store, true) +
' :: ' +
chalk.yellow(message)
);
} }
return `${buildSetupString(topic, store)} :: ${message}`; return `${buildSetupString(topic, store)} :: ${message}`;
}, },
noResponse(link: Link, store: Store, color?: boolean): string { noResponse(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('NO RESPONSE'); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('NO RESPONSE')
);
} }
return `${buildProductString(link, store)} :: NO RESPONSE`; return `${buildProductString(link, store)} :: NO RESPONSE`;
}, },
outOfStock(link: Link, store: Store, color?: boolean): string { outOfStock(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.red('OUT OF STOCK'); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.red('OUT OF STOCK')
);
} }
return `${buildProductString(link, store)} :: OUT OF STOCK`; return `${buildProductString(link, store)} :: OUT OF STOCK`;
}, },
productInStock(link: Link): string {
let productString = `Product Page: ${link.url}`;
if (link.cartUrl) productString += `\nAdd To Cart Link: ${link.cartUrl}`;
return productString;
},
rateLimit(link: Link, store: Store, color?: boolean): string { rateLimit(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('RATE LIMIT EXCEEDED'); return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('RATE LIMIT EXCEEDED')
);
} }
return `${buildProductString(link, store)} :: RATE LIMIT EXCEEDED`; return `${buildProductString(link, store)} :: RATE LIMIT EXCEEDED`;
},
recursionLimit(link: Link, store: Store, color?: boolean): string {
if (color) {
return (
'✖ ' +
buildProductString(link, store, true) +
' :: ' +
chalk.yellow('CLOUDFLARE RETRY LIMIT REACHED, ABORT')
);
} }
return `${buildProductString(
link,
store
)} :: CLOUDFLARE RETRY LIMIT REACHED, ABORT`;
},
}; };
function buildSetupString(topic: string, store: Store, color?: boolean): string { function buildSetupString(
topic: string,
store: Store,
color?: boolean
): string {
if (color) { if (color) {
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`); return chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`);
} }
@@ -125,7 +241,10 @@ function buildSetupString(topic: string, store: Store, color?: boolean): string
function buildProductString(link: Link, store: Store, color?: boolean): string { function buildProductString(link: Link, store: Store, color?: boolean): string {
if (color) { if (color) {
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [${link.brand} (${link.series})] ${link.model}`); return (
chalk.cyan(`[${store.name}]`) +
chalk.grey(` [${link.brand} (${link.series})] ${link.model}`)
);
} }
return `[${store.name}] [${link.brand} (${link.series})] ${link.model}`; return `[${store.name}] [${link.brand} (${link.series})] ${link.model}`;
+8 -2
View File
@@ -1,17 +1,23 @@
import {Link, Store} from '../store/model'; import {Link, Store} from '../store/model';
import {Print, logger} from '../logger'; import {Print, logger} from '../logger';
import {config} from '../config'; import {config} from '../config';
import {join} from 'path';
import notifier from 'node-notifier'; import notifier from 'node-notifier';
const desktop = config.notifications.desktop; const {desktop} = config.notifications;
export function sendDesktopNotification(link: Link, store: Store) { export function sendDesktopNotification(link: Link, store: Store) {
if (desktop) { if (desktop) {
logger.debug('↗ sending desktop notification'); logger.debug('↗ sending desktop notification');
(async () => { (async () => {
notifier.notify({ notifier.notify({
icon: join(
__dirname,
'../../../docs/assets/images/streetmerchant-logo.png'
),
message: link.cartUrl ? link.cartUrl : link.url, message: link.cartUrl ? link.cartUrl : link.url,
title: Print.inStock(link, store) open: link.cartUrl ? link.cartUrl : link.url,
title: Print.inStock(link, store),
}); });
logger.info('✔ desktop notification sent'); logger.info('✔ desktop notification sent');
+57 -20
View File
@@ -1,43 +1,80 @@
import {Link, Store} from '../store/model'; import {Link, Store} from '../store/model';
import {MessageBuilder, Webhook} from 'discord-webhook-node'; import Discord from 'discord.js';
import {config} from '../config'; import {config} from '../config';
import {logger} from '../logger'; import {logger} from '../logger';
const discord = config.notifications.discord; const {notifyGroup, webhooks, notifyGroupSeries} = config.notifications.discord;
const hooks = discord.webHookUrl;
const notifyGroup = discord.notifyGroup; function getIdAndToken(webhook: string) {
const match = /.*\/webhooks\/(\d+)\/(.+)/.exec(webhook);
if (!match) {
throw new Error('could not get discord webhook');
}
return {
id: match[1],
token: match[2],
};
}
export function sendDiscordMessage(link: Link, store: Store) { export function sendDiscordMessage(link: Link, store: Store) {
if (discord.webHookUrl.length > 0) { if (webhooks.length > 0) {
logger.debug('↗ sending discord message'); logger.debug('↗ sending discord message');
(async () => { (async () => {
try { try {
const embed = new MessageBuilder(); const embed = new Discord.MessageEmbed()
embed.setTitle('Stock Notification'); .setTitle('_**Stock alert!**_')
embed.addField('URL', link.cartUrl ? link.cartUrl : link.url, true); .setDescription(
'> provided by [streetmerchant](https://github.com/jef/streetmerchant) with :heart:'
)
.setThumbnail(
'https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-logo.png'
)
.setColor('#52b788')
.setTimestamp();
embed.addField('Store', store.name, true); embed.addField('Store', store.name, true);
if (link.price)
embed.addField('Price', `${store.currency}${link.price}`, true);
embed.addField('Product Page', link.url);
if (link.cartUrl) embed.addField('Add to Cart', link.cartUrl);
embed.addField('Brand', link.brand, true); embed.addField('Brand', link.brand, true);
embed.addField('Series', link.series, true);
embed.addField('Model', link.model, true); embed.addField('Model', link.model, true);
embed.addField('Series', link.series, true);
if (notifyGroup) {
embed.setText(notifyGroup.join(' '));
}
embed.setColor(0x76B900);
embed.setTimestamp(); embed.setTimestamp();
const promises = []; let notifyText: string[] = [];
for (const hook of hooks) {
promises.push(new Webhook(hook).send(embed)); if (notifyGroup) {
notifyText = notifyText.concat(notifyGroup);
} }
await Promise.all(promises); if (Object.keys(notifyGroupSeries).indexOf(link.series) !== 0) {
notifyText = notifyText.concat(notifyGroupSeries[link.series]);
}
const promises = [];
for (const webhook of webhooks) {
const {id, token} = getIdAndToken(webhook);
const client = new Discord.WebhookClient(id, token);
promises.push({
client,
message: client.send(notifyText.join(' '), {
embeds: [embed],
username: 'streetmerchant',
}),
});
}
(await Promise.all(promises)).forEach(({client}) => client.destroy());
logger.info('✔ discord message sent'); logger.info('✔ discord message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send discord message', error); logger.error("✖ couldn't send discord message", error);
} }
})(); })();
} }
+11 -9
View File
@@ -4,7 +4,7 @@ import Mail from 'nodemailer/lib/mailer';
import {config} from '../config'; import {config} from '../config';
import nodemailer from 'nodemailer'; import nodemailer from 'nodemailer';
const email = config.notifications.email; const {email} = config.notifications;
const transportOptions: any = {}; const transportOptions: any = {};
@@ -22,7 +22,7 @@ if (email.smtpAddress) {
} }
export const transporter = nodemailer.createTransport({ export const transporter = nodemailer.createTransport({
...transportOptions ...transportOptions,
}); });
export function sendEmail(link: Link, store: Store) { export function sendEmail(link: Link, store: Store) {
@@ -30,21 +30,23 @@ export function sendEmail(link: Link, store: Store) {
logger.debug('↗ sending email'); logger.debug('↗ sending email');
const mailOptions: Mail.Options = { const mailOptions: Mail.Options = {
attachments: link.screenshot ? [ attachments: link.screenshot
? [
{ {
filename: link.screenshot, filename: link.screenshot,
path: `./${link.screenshot}` path: `./${link.screenshot}`,
} },
] : undefined, ]
: undefined,
from: email.username, from: email.username,
subject: Print.inStock(link, store), subject: Print.inStock(link, store),
text: link.cartUrl ? link.cartUrl : link.url, text: Print.productInStock(link),
to: email.to to: email.to,
}; };
transporter.sendMail(mailOptions, error => { transporter.sendMail(mailOptions, error => {
if (error) { if (error) {
logger.error('✖ couldn\'t send email', error); logger.error("✖ couldn't send email", error);
} else { } else {
logger.info('✔ email sent'); logger.info('✔ email sent');
} }
+25 -18
View File
@@ -3,20 +3,25 @@ import MqttClient, {IClientOptions, IClientPublishOptions} from 'mqtt';
import {Print, logger} from '../logger'; import {Print, logger} from '../logger';
import {config} from '../config'; import {config} from '../config';
const mqtt = config.notifications.mqtt; const {mqtt} = config.notifications;
let client: MqttClient.Client; let client: MqttClient.Client;
if (mqtt.broker) { if (mqtt.broker) {
if (checkInsecureUsage(mqtt.password, mqtt.broker)) { if (checkInsecureUsage(mqtt.password, mqtt.broker)) {
logger.warn('✖ Insecure transport of password - Only use credentials with MQTT brokers on private networks.'); logger.warn(
'✖ Insecure transport of password - Only use credentials with MQTT brokers on private networks.'
);
} else { } else {
const clientOptions: IClientOptions = { const clientOptions: IClientOptions = {
clean: (mqtt.clientId === ''), clean: mqtt.clientId === '',
clientId: mqtt.clientId === '' ? undefined : mqtt.clientId, clientId: mqtt.clientId === '' ? undefined : mqtt.clientId,
password: mqtt.password === '' ? undefined : mqtt.password, password: mqtt.password === '' ? undefined : mqtt.password,
username: mqtt.username === '' ? undefined : mqtt.username username: mqtt.username === '' ? undefined : mqtt.username,
}; };
client = MqttClient.connect(`mqtt://${mqtt.broker}:${mqtt.port}`, clientOptions); client = MqttClient.connect(
`mqtt://${mqtt.broker}:${mqtt.port}`,
clientOptions
);
} }
} }
@@ -26,22 +31,21 @@ export function sendMqttMessage(link: Link, store: Store) {
(async () => { (async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url; const givenUrl = link.cartUrl ? link.cartUrl : link.url;
const message = `{"msg":"${Print.inStock(link, store)}", "url":"${givenUrl}"}`; const message = `{"msg":"${Print.inStock(
link,
store
)}", "url":"${givenUrl}"}`;
const topic = generateTopic(link, store, mqtt.topic); const topic = generateTopic(link, store, mqtt.topic);
const pubOptions: IClientPublishOptions = { const pubOptions: IClientPublishOptions = {
qos: mqtt.qos as 0 | 1 | 2, qos: mqtt.qos as 0 | 1 | 2,
retain: false retain: false,
}; };
try { try {
client.publish( client.publish(topic, message, pubOptions);
topic,
message,
pubOptions
);
logger.info('✔ mqtt message sent'); logger.info('✔ mqtt message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send mqtt message', error); logger.error("✖ couldn't send mqtt message", error);
} }
})(); })();
} }
@@ -50,7 +54,8 @@ export function sendMqttMessage(link: Link, store: Store) {
function generateTopic(link: Link, store: Store, topic: string): string { function generateTopic(link: Link, store: Store, topic: string): string {
topic.trim(); topic.trim();
topic = topic.replace(/^\//, ''); topic = topic.replace(/^\//, '');
topic = topic.replace(/%series%/g, link.series) topic = topic
.replace(/%series%/g, link.series)
.replace(/%brand%/g, link.brand) .replace(/%brand%/g, link.brand)
.replace(/%model%/g, link.model) .replace(/%model%/g, link.model)
.replace(/%store%/g, store.name); .replace(/%store%/g, store.name);
@@ -60,7 +65,7 @@ function generateTopic(link: Link, store: Store, topic: string): string {
/** /**
* Basic protection against sending credentials in the clear over public networks. * Basic protection against sending credentials in the clear over public networks.
* - Returns 'true' if password is supplied in .env but address/URL is not part of a private network * - Returns 'true' if password is supplied in dotenv but address/URL is not part of a private network
* - Private networks evaluated: Class A, B, or C private IP's or linklocal URL ("*.local") * - Private networks evaluated: Class A, B, or C private IP's or linklocal URL ("*.local")
* - TLS could be implemented, however, the majority of MQTT services on the internet do not require user authentication. * - TLS could be implemented, however, the majority of MQTT services on the internet do not require user authentication.
* - If you find a 'cloud' MQTT broker requiring authentication for publishing alerts, consider using another MQTT service (for now). * - If you find a 'cloud' MQTT broker requiring authentication for publishing alerts, consider using another MQTT service (for now).
@@ -68,10 +73,12 @@ function generateTopic(link: Link, store: Store, topic: string): string {
*/ */
function checkInsecureUsage(pass: string, address: string): boolean { function checkInsecureUsage(pass: string, address: string): boolean {
if (pass !== '') { if (pass !== '') {
if (isClassANet(address) || if (
isClassANet(address) ||
isClassBNet(address) || isClassBNet(address) ||
isClassCNet(address) || isClassCNet(address) ||
isLinkLocal(address)) { isLinkLocal(address)
) {
logger.debug(`MQTT using private network broker: ${address}`); logger.debug(`MQTT using private network broker: ${address}`);
} else { } else {
logger.debug(`MQTT using public network broker: ${address}`); logger.debug(`MQTT using public network broker: ${address}`);
+6 -2
View File
@@ -1,4 +1,5 @@
import {Link, Store} from '../store/model'; import {Link, Store} from '../store/model';
import {adjustPhilipsHueLights} from './philips-hue';
import {playSound} from './sound'; import {playSound} from './sound';
import {sendDesktopNotification} from './desktop'; import {sendDesktopNotification} from './desktop';
import {sendDiscordMessage} from './discord'; import {sendDiscordMessage} from './discord';
@@ -13,15 +14,17 @@ import {sendTelegramMessage} from './telegram';
import {sendTweet} from './twitter'; import {sendTweet} from './twitter';
import {sendTwilioMessage} from './twilio'; import {sendTwilioMessage} from './twilio';
import {sendTwitchMessage} from './twitch'; import {sendTwitchMessage} from './twitch';
import {updateRedis} from './redis';
export function sendNotification(link: Link, store: Store) { export function sendNotification(link: Link, store: Store) {
// Priority // Priority
playSound(); playSound();
sendDiscordMessage(link, store);
sendDesktopNotification(link, store);
sendEmail(link, store); sendEmail(link, store);
sendSms(link, store); sendSms(link, store);
sendDesktopNotification(link, store);
// Non-priority // Non-priority
sendDiscordMessage(link, store); adjustPhilipsHueLights();
sendMqttMessage(link, store); sendMqttMessage(link, store);
sendPagerDutyNotification(link, store); sendPagerDutyNotification(link, store);
sendPushbulletNotification(link, store); sendPushbulletNotification(link, store);
@@ -31,4 +34,5 @@ export function sendNotification(link: Link, store: Store) {
sendTweet(link, store); sendTweet(link, store);
sendTwilioMessage(link, store); sendTwilioMessage(link, store);
sendTwitchMessage(link, store); sendTwitchMessage(link, store);
updateRedis(link, store);
} }
+5 -6
View File
@@ -8,12 +8,11 @@ const pd = new PDClient('');
export function sendPagerDutyNotification(link: Link, store: Store) { export function sendPagerDutyNotification(link: Link, store: Store) {
if (config.notifications.pagerduty.integrationKey) { if (config.notifications.pagerduty.integrationKey) {
logger.debug('↗ sending pagerduty message'); logger.debug('↗ sending pagerduty message');
const links = [ const links = [{href: link.url, text: 'Visit Store'}];
{href: link.url, text: 'Visit Store'}
];
if (link.cartUrl) { if (link.cartUrl) {
links.push({ links.push({
href: link.cartUrl, text: 'Add to Cart' href: link.cartUrl,
text: 'Add to Cart',
}); });
} }
@@ -24,9 +23,9 @@ export function sendPagerDutyNotification(link: Link, store: Store) {
links, links,
severity: config.notifications.pagerduty.severity, severity: config.notifications.pagerduty.severity,
source: store.name, source: store.name,
summary: Print.inStock(link, store) summary: Print.inStock(link, store),
}, },
routing_key: config.notifications.pagerduty.integrationKey routing_key: config.notifications.pagerduty.integrationKey,
}); });
} }
} }
+127
View File
@@ -0,0 +1,127 @@
import type Api from 'node-hue-api/lib/api/Api';
import {config} from '../config';
import {v3 as hueAPI} from 'node-hue-api';
import {logger} from '../logger';
const {LightState} = hueAPI.lightStates;
const {
apiKey,
bridgeIp,
lightIds,
lightColor,
lightPattern,
clientId,
clientSecret,
accessToken,
refreshToken,
remoteApiUsername,
} = config.notifications.philips_hue;
// Default Light State
const lightState = new LightState()
.on(true)
.brightness(100)
.rgb(46.27, 72.55, 0);
const adjustLightsWithAPI = (hueBridge: Api) => {
logger.debug('Connected to Philips Hue bridge.');
// Set the custom light state (COLOR and METHOD here)
if (lightColor) {
const rgbArray = lightColor.split(',');
// If there's not three values, must not be RGB
if (rgbArray.length === 3) {
lightState.rgb(rgbArray[0], rgbArray[1], rgbArray[2]);
} else {
logger.debug('✖ Error assigning RGB Values');
}
}
// If blink is specified, then blink the lights
if (lightPattern === 'blink') {
lightState.alertLong();
}
// If we've been given light IDs, then only adjust those IDs
if (lightIds) {
const arrayOfIDs = lightIds.split(',');
arrayOfIDs.forEach(light => {
logger.debug('adjusting specified lights');
(hueBridge.lights.setLightState(light, lightState) as Promise<any>).catch(
(error: Error) => {
logger.error('Failed to adjust specified lights.');
logger.error(error);
throw error;
}
);
});
} else {
// Adjust all light IDs
hueBridge.lights
.getAll()
.then((allLights: any[]) => {
allLights.forEach((light: any) => {
logger.debug('adjusting all hue lights');
(hueBridge.lights.setLightState(
light,
lightState
) as Promise<any>).catch((error: Error) => {
logger.error('Failed to adjust all lights.');
logger.error(error);
throw error;
});
});
})
.catch((error: Error) => {
logger.error('Failed to get all lights.');
logger.error(error);
throw error;
});
}
};
export function adjustPhilipsHueLights() {
// Check if the required variables have been set
if (apiKey && bridgeIp) {
logger.info('↗ adjusting Philips Hue lights over LAN');
(async () => {
logger.debug(
'Attempting to connect to Philips Hue bridge at ' + bridgeIp
);
hueAPI.api
.createLocal(bridgeIp)
.connect(apiKey)
.then(
hueBridge => {
adjustLightsWithAPI(hueBridge);
logger.info('✔ adjusted Philips Hue lights over LAN');
},
(error: Error) => {
logger.error("✖ couldn't adjust hue lights.", error);
}
);
})();
} else if (apiKey && clientId && clientSecret) {
logger.info('↗ adjusting Philips Hue lights over cloud');
(async () => {
logger.debug('Attempting to connect to Philips Hue bridge over cloud');
const remoteBootstrap = hueAPI.api.createRemote(clientId, clientSecret);
if (accessToken && refreshToken) {
remoteBootstrap
.connectWithTokens(accessToken, refreshToken, remoteApiUsername)
.then(
hueBridge => {
adjustLightsWithAPI(hueBridge);
logger.info('✔ adjusted Philips Hue lights over cloud');
},
(error: Error) => {
logger.error(
'Failed to get a remote Philips Hue connection using supplied tokens.'
);
logger.error(error);
throw error;
}
);
}
})();
}
}
+4 -3
View File
@@ -3,7 +3,7 @@ import {Print, logger} from '../logger';
import PushBullet from '@jef/pushbullet'; import PushBullet from '@jef/pushbullet';
import {config} from '../config'; import {config} from '../config';
const pushbullet = config.notifications.pushbullet; const {pushbullet} = config.notifications;
export function sendPushbulletNotification(link: Link, store: Store) { export function sendPushbulletNotification(link: Link, store: Store) {
if (pushbullet) { if (pushbullet) {
@@ -17,10 +17,11 @@ export function sendPushbulletNotification(link: Link, store: Store) {
link.cartUrl ? link.cartUrl : link.url, link.cartUrl ? link.cartUrl : link.url,
(error: Error) => { (error: Error) => {
if (error) { if (error) {
logger.error('✖ couldn\'t send pushbullet message', error); logger.error("✖ couldn't send pushbullet message", error);
} else { } else {
logger.info('✔ pushbullet message sent'); logger.info('✔ pushbullet message sent');
} }
}); }
);
} }
} }
+20 -8
View File
@@ -3,25 +3,37 @@ import {Print, logger} from '../logger';
import Push, {PushoverMessage} from 'pushover-notifications'; import Push, {PushoverMessage} from 'pushover-notifications';
import {config} from '../config'; import {config} from '../config';
const pushover = config.notifications.pushover; const {pushover} = config.notifications;
const push = new Push({
token: pushover.token,
user: pushover.username
});
export function sendPushoverNotification(link: Link, store: Store) { export function sendPushoverNotification(link: Link, store: Store) {
if (pushover.token && pushover.username) { if (pushover.token && pushover.username) {
logger.debug('↗ sending pushover message'); logger.debug('↗ sending pushover message');
const message: PushoverMessage = { const push = new Push({
token: pushover.token,
user: pushover.username,
});
const message: PushoverMessage =
pushover.priority < 2
? {
message: link.cartUrl ? link.cartUrl : link.url, message: link.cartUrl ? link.cartUrl : link.url,
priority: pushover.priority, priority: pushover.priority,
title: Print.inStock(link, store) title: Print.inStock(link, store),
...(link.screenshot && {file: `./${link.screenshot}`}),
}
: {
expire: pushover.expire,
message: link.cartUrl ? link.cartUrl : link.url,
priority: pushover.priority,
retry: pushover.retry,
title: Print.inStock(link, store),
...(link.screenshot && {file: `./${link.screenshot}`}),
}; };
push.send(message, (error: Error) => { push.send(message, (error: Error) => {
if (error) { if (error) {
logger.error('✖ couldn\'t send pushover message', error); logger.error("✖ couldn't send pushover message", error);
} else { } else {
logger.info('✔ pushover message sent'); logger.info('✔ pushover message sent');
} }
+45
View File
@@ -0,0 +1,45 @@
import {Link, Store} from '../store/model';
import redis, {RedisClient} from 'redis';
import {config} from '../config';
import {logger} from '../logger';
const {url} = config.notifications.redis;
let client: RedisClient;
function initRedis(): RedisClient | null {
if (url) {
client = redis.createClient({url});
}
return null;
}
export function updateRedis(link: Link, store: Store) {
try {
if (client) {
const key = `${store.name}:${link.brand}:${link.model}`
.split(' ')
.join('-');
const value = {
...link,
labels: store.labels,
links: store.links,
name: store.name,
updatedAt: new Date().toUTCString(),
};
const redisUpdated = client.set(key, JSON.stringify(value));
if (redisUpdated) {
logger.info('✔ redis updated');
} else {
logger.error(`✖ couldn't update redis for key (${key})`);
}
}
} catch (error: unknown) {
logger.error("✖ couldn't update redis", error);
}
}
initRedis();
+7 -9
View File
@@ -3,13 +3,11 @@ import {Print, logger} from '../logger';
import {WebClient} from '@slack/web-api'; import {WebClient} from '@slack/web-api';
import {config} from '../config'; import {config} from '../config';
const slack = config.notifications.slack; const {channel, token} = config.notifications.slack;
const channel = slack.channel;
const token = slack.token;
const web = new WebClient(token); const web = new WebClient(token);
export function sendSlackMessage(link: Link, store: Store) { export function sendSlackMessage(link: Link, store: Store) {
if (slack.channel && slack.token) { if (channel && token) {
logger.debug('↗ sending slack message'); logger.debug('↗ sending slack message');
(async () => { (async () => {
@@ -17,18 +15,18 @@ export function sendSlackMessage(link: Link, store: Store) {
try { try {
const result = await web.chat.postMessage({ const result = await web.chat.postMessage({
channel, channel: channel.replace('#', ''),
text: `${Print.inStock(link, store)}\n${givenUrl}` text: `${Print.inStock(link, store)}\n${givenUrl}`,
}); });
if (!result.ok) { if (!result.ok) {
logger.error('✖ couldn\'t send slack message', result); logger.error("✖ couldn't send slack message", result);
return; return;
} }
logger.info('✔ slack message sent'); logger.info('✔ slack message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send slack message', error); logger.error("✖ couldn't send slack message", error);
} }
})(); })();
} }
+48 -19
View File
@@ -4,48 +4,77 @@ import Mail from 'nodemailer/lib/mailer';
import {config} from '../config'; import {config} from '../config';
import {transporter} from './email'; import {transporter} from './email';
if (config.notifications.phone.number && !config.notifications.email.username) { const {email, phone} = config.notifications;
logger.warn('✖ in order to receive sms alerts, email notifications must also be configured');
if (phone.number.length > 0 && (!email.username || !email.password)) {
logger.warn(
'✖ in order to receive sms alerts, email notifications must also be configured'
);
} }
const [email, phone] = [config.notifications.email, config.notifications.phone]; if (phone.carrier.length !== phone.number.length) {
logger.warn(
'✖ the number of carriers must match the number of phone numbers',
{carrier: phone.carrier, number: phone.number}
);
}
export function sendSms(link: Link, store: Store) { export function sendSms(link: Link, store: Store) {
if (phone.number) { for (
logger.debug('↗ sending sms'); let i = 0;
const carrier = phone.carrier; i < Math.max(phone.number.length, phone.carrier.length);
i++
) {
const currentNumber = phone.number[i];
const currentCarrier = phone.carrier[i];
if (!currentNumber) {
logger.error(`${currentCarrier} is not associated with a number`);
continue;
} else if (!currentCarrier) {
logger.error(`${currentNumber} is not associated with a carrier`);
continue;
}
if (!phone.availableCarriers.has(currentCarrier)) {
logger.error(`✖ unknown carrier ${currentCarrier}`);
continue;
}
logger.debug('↗ sending sms');
if (carrier && phone.availableCarriers.has(carrier)) {
const mailOptions: Mail.Options = { const mailOptions: Mail.Options = {
attachments: link.screenshot ? [ attachments: link.screenshot
? [
{ {
filename: link.screenshot, filename: link.screenshot,
path: `./${link.screenshot}` path: `./${link.screenshot}`,
} },
] : undefined, ]
: undefined,
from: email.username, from: email.username,
subject: Print.inStock(link, store, false, true), subject: Print.inStock(link, store, false, true),
text: link.cartUrl ? link.cartUrl : link.url, text: link.cartUrl ? link.cartUrl : link.url,
to: generateAddress() to: generateAddress(currentNumber, currentCarrier),
}; };
transporter.sendMail(mailOptions, error => { transporter.sendMail(mailOptions, error => {
if (error) { if (error) {
logger.error('✖ couldn\'t send sms', error); logger.error(
`✖ couldn't send sms to ${currentNumber} for carrier ${currentCarrier}`,
error
);
} else { } else {
logger.info('✔ sms sent'); logger.info('✔ sms sent');
} }
}); });
} }
}
} }
function generateAddress() { function generateAddress(number: string, carrier: string): string {
const carrier = phone.carrier;
if (carrier && phone.availableCarriers.has(carrier)) { if (carrier && phone.availableCarriers.has(carrier)) {
return [phone.number, phone.availableCarriers.get(carrier)].join('@'); return [number, phone.availableCarriers.get(carrier)].join('@');
} }
logger.error('✖ unknown carrier', carrier); return '';
} }
+5 -3
View File
@@ -6,10 +6,12 @@ import {logger} from '../logger';
let player: PlaySound; let player: PlaySound;
if (config.notifications.playSound) { if (config.notifications.playSound) {
player = playerLib(); player = config.notifications.soundPlayer
? playerLib({players: [config.notifications.soundPlayer]})
: playerLib();
if (player.player === null) { if (player.player === null) {
logger.warn('✖ couldn\'t find sound player'); logger.warn("✖ couldn't find sound player");
} else { } else {
const playerName = player.player; const playerName = player.player;
logger.info(`✔ sound player found: ${playerName}`); logger.info(`✔ sound player found: ${playerName}`);
@@ -28,7 +30,7 @@ export function playSound() {
player.play(config.notifications.playSound, (error: Error) => { player.play(config.notifications.playSound, (error: Error) => {
if (error) { if (error) {
logger.error('✖ couldn\'t play sound', error); logger.error("✖ couldn't play sound", error);
} }
logger.info('✔ played sound'); logger.info('✔ played sound');
+11 -6
View File
@@ -3,10 +3,10 @@ import {Print, logger} from '../logger';
import {TelegramClient} from 'messaging-api-telegram'; import {TelegramClient} from 'messaging-api-telegram';
import {config} from '../config'; import {config} from '../config';
const telegram = config.notifications.telegram; const {telegram} = config.notifications;
const client = new TelegramClient({ const client = new TelegramClient({
accessToken: telegram.accessToken accessToken: telegram.accessToken,
}); });
export function sendTelegramMessage(link: Link, store: Store) { export function sendTelegramMessage(link: Link, store: Store) {
@@ -14,15 +14,20 @@ export function sendTelegramMessage(link: Link, store: Store) {
logger.debug('↗ sending telegram message'); logger.debug('↗ sending telegram message');
(async () => { (async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url; const message = Print.productInStock(link);
const results = []; const results = [];
for (const chatId of telegram.chatId) { for (const chatId of telegram.chatId) {
try { try {
results.push(client.sendMessage(chatId, `${Print.inStock(link, store)}\n${givenUrl}`)); results.push(
client.sendMessage(
chatId,
`${Print.inStock(link, store)}\n${message}`
)
);
logger.info('✔ telegram message sent'); logger.info('✔ telegram message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send telegram message', error); logger.error("✖ couldn't send telegram message", error);
} }
} }
+14 -7
View File
@@ -3,7 +3,7 @@ import {Print, logger} from '../logger';
import {Twilio} from 'twilio'; import {Twilio} from 'twilio';
import {config} from '../config'; import {config} from '../config';
const twilio = config.notifications.twilio; const {twilio} = config.notifications;
let client: Twilio; let client: Twilio;
if (twilio.accountSid && twilio.authToken) { if (twilio.accountSid && twilio.authToken) {
@@ -17,17 +17,24 @@ export function sendTwilioMessage(link: Link, store: Store) {
(async () => { (async () => {
const givenUrl = link.cartUrl ? link.cartUrl : link.url; const givenUrl = link.cartUrl ? link.cartUrl : link.url;
const message = `${Print.inStock(link, store)}\n${givenUrl}`; const message = `${Print.inStock(link, store)}\n${givenUrl}`;
const numbers = twilio.to.split(',');
const results = [];
for (const number of numbers) {
try { try {
await client.messages.create({ results.push(
client.messages.create({
body: message, body: message,
from: twilio.from, from: twilio.from,
to: twilio.to to: number,
}); })
);
logger.info('✔ twilio message sent'); logger.info('✔ twilio message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send twilio message', error); logger.error("✖ couldn't send twilio message", error);
} }
}
await Promise.all(results);
})(); })();
} }
} }
+38 -15
View File
@@ -5,7 +5,7 @@ import {existsSync, promises, readFileSync} from 'fs';
import {ChatClient} from 'twitch-chat-client'; import {ChatClient} from 'twitch-chat-client';
import {config} from '../config'; import {config} from '../config';
const twitch = config.notifications.twitch; const {twitch} = config.notifications;
const messages: string[] = []; const messages: string[] = [];
let alreadySaying = false; let alreadySaying = false;
@@ -13,11 +13,14 @@ let alreadySaying = false;
let tokenData = { let tokenData = {
accessToken: twitch.accessToken, accessToken: twitch.accessToken,
expiryTimestamp: 0, expiryTimestamp: 0,
refreshToken: twitch.refreshToken refreshToken: twitch.refreshToken,
}; };
if (existsSync('./twitch.json')) { if (existsSync('./twitch.json')) {
tokenData = {...JSON.parse(readFileSync('./twitch.json', 'utf-8')), ...tokenData}; tokenData = {
...JSON.parse(readFileSync('./twitch.json', 'utf-8')),
...tokenData,
};
} }
const chatClient: ChatClient = new ChatClient( const chatClient: ChatClient = new ChatClient(
@@ -25,19 +28,31 @@ const chatClient: ChatClient = new ChatClient(
new StaticAuthProvider(twitch.clientId, tokenData.accessToken), new StaticAuthProvider(twitch.clientId, tokenData.accessToken),
{ {
clientSecret: twitch.clientSecret, clientSecret: twitch.clientSecret,
expiry: tokenData.expiryTimestamp === null ? null : new Date(tokenData.expiryTimestamp), expiry:
tokenData.expiryTimestamp === null
? null
: new Date(tokenData.expiryTimestamp),
onRefresh: async ({accessToken, refreshToken, expiryDate}) => { onRefresh: async ({accessToken, refreshToken, expiryDate}) => {
return promises.writeFile('./twitch.json', JSON.stringify({ return promises.writeFile(
'./twitch.json',
JSON.stringify(
{
accessToken, accessToken,
expiryTimestamp: expiryDate === null ? null : expiryDate.getTime(), expiryTimestamp:
refreshToken expiryDate === null ? null : expiryDate.getTime(),
}, null, 4), 'utf-8'); refreshToken,
}, },
refreshToken: tokenData.refreshToken null,
4
),
'utf-8'
);
},
refreshToken: tokenData.refreshToken,
} }
), ),
{ {
channels: [twitch.channel] channels: [twitch.channel],
} }
); );
@@ -48,10 +63,10 @@ chatClient.onJoin((channel: string, user: string) => {
if (message !== undefined) { if (message !== undefined) {
try { try {
chatClient.say(channel, message); void chatClient.say(channel, message);
logger.info('✔ twitch message sent'); logger.info('✔ twitch message sent');
} catch (error) { } catch (error: unknown) {
logger.error('✖ couldn\'t send twitch message', error); logger.error("✖ couldn't send twitch message", error);
} }
} }
} }
@@ -65,10 +80,18 @@ chatClient.onDisconnect(() => {
}); });
export function sendTwitchMessage(link: Link, store: Store) { export function sendTwitchMessage(link: Link, store: Store) {
if (tokenData.accessToken && twitch.channel && twitch.clientId && twitch.clientSecret && tokenData.refreshToken) { if (
tokenData.accessToken &&
twitch.channel &&
twitch.clientId &&
twitch.clientSecret &&
tokenData.refreshToken
) {
logger.debug('↗ sending twitch message'); logger.debug('↗ sending twitch message');
messages.push(`${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`); messages.push(
`${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`
);
if (!alreadySaying) { if (!alreadySaying) {
alreadySaying = true; alreadySaying = true;
+12 -5
View File
@@ -3,20 +3,27 @@ import {Print, logger} from '../logger';
import Twitter from 'twitter'; import Twitter from 'twitter';
import {config} from '../config'; import {config} from '../config';
const twitter = config.notifications.twitter; const {twitter} = config.notifications;
const client = new Twitter({ const client = new Twitter({
access_token_key: twitter.accessTokenKey, access_token_key: twitter.accessTokenKey,
access_token_secret: twitter.accessTokenSecret, access_token_secret: twitter.accessTokenSecret,
consumer_key: twitter.consumerKey, consumer_key: twitter.consumerKey,
consumer_secret: twitter.consumerSecret consumer_secret: twitter.consumerSecret,
}); });
export function sendTweet(link: Link, store: Store) { export function sendTweet(link: Link, store: Store) {
if (twitter.accessTokenKey && twitter.accessTokenSecret && twitter.consumerKey && twitter.consumerSecret) { if (
twitter.accessTokenKey &&
twitter.accessTokenSecret &&
twitter.consumerKey &&
twitter.consumerSecret
) {
logger.debug('↗ sending twitter message'); logger.debug('↗ sending twitter message');
let status = `${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`; let status = `${Print.inStock(link, store)}\n${
link.cartUrl ? link.cartUrl : link.url
}`;
if (twitter.tweetTags) { if (twitter.tweetTags) {
status += `\n\n${twitter.tweetTags}`; status += `\n\n${twitter.tweetTags}`;
@@ -24,7 +31,7 @@ export function sendTweet(link: Link, store: Store) {
client.post('statuses/update', {status}, error => { client.post('statuses/update', {status}, error => {
if (error) { if (error) {
logger.error('✖ couldn\'t send twitter notification', error); logger.error("✖ couldn't send twitter notification", error);
} else { } else {
logger.info('✔ twitter notification sent'); logger.info('✔ twitter notification sent');
} }
+10 -3
View File
@@ -19,7 +19,9 @@ function addNewLinks(store: Store, links: Link[], series: Series) {
return; return;
} }
logger.debug(Print.message(`FOUND ${newLinks.length} STORE LINKS`, series, store, true)); logger.debug(
Print.message(`FOUND ${newLinks.length} STORE LINKS`, series, store, true)
);
logger.debug(JSON.stringify(newLinks, null, 2)); logger.debug(JSON.stringify(newLinks, null, 2));
store.links = store.links.concat(newLinks); store.links = store.links.concat(newLinks);
@@ -32,6 +34,7 @@ export async function fetchLinks(store: Store, browser: Browser) {
const promises: Array<Promise<void>> = []; const promises: Array<Promise<void>> = [];
// eslint-disable-next-line prefer-const
for (let {series, url} of store.linksBuilder.urls) { for (let {series, url} of store.linksBuilder.urls) {
if (!filterSeries(series)) { if (!filterSeries(series)) {
continue; continue;
@@ -43,7 +46,9 @@ export async function fetchLinks(store: Store, browser: Browser) {
url = [url]; url = [url];
} }
url.map(x => promises.push(usingResponse(browser, x, async response => { url.map(x =>
promises.push(
usingResponse(browser, x, async response => {
const text = await response?.text(); const text = await response?.text();
if (!text) { if (!text) {
@@ -55,7 +60,9 @@ export async function fetchLinks(store: Store, browser: Browser) {
const links = store.linksBuilder!.builder(docElement, series); const links = store.linksBuilder!.builder(docElement, series);
addNewLinks(store, links, series); addNewLinks(store, links, series);
}))); })
)
);
} }
await Promise.all(promises); await Promise.all(promises);
+6 -2
View File
@@ -30,12 +30,16 @@ function filterModel(model: Link['model'], series: Link['series']): boolean {
for (const configModelEntry of config.store.showOnlyModels) { for (const configModelEntry of config.store.showOnlyModels) {
const sanitizedConfigModel = configModelEntry.name.replace(/\s/g, ''); const sanitizedConfigModel = configModelEntry.name.replace(/\s/g, '');
const sanitizedConfigSeries = configModelEntry.series.replace(/\s/g, ''); const sanitizedConfigSeries = configModelEntry.series.replace(/\s/g, '');
if (sanitizedConfigSeries ? if (sanitizedConfigSeries) {
sanitizedSeries === sanitizedConfigSeries && sanitizedModel === sanitizedConfigModel : if (
sanitizedSeries === sanitizedConfigSeries &&
sanitizedModel === sanitizedConfigModel sanitizedModel === sanitizedConfigModel
) { ) {
return true; return true;
} }
} else if (sanitizedModel === sanitizedConfigModel) {
return true;
}
} }
return false; return false;
+59 -30
View File
@@ -9,36 +9,50 @@ export type Selector = {
}; };
function isElementArray(query: LabelQuery): query is Element[] { function isElementArray(query: LabelQuery): query is Element[] {
return Array.isArray(query) && query.length > 0 && typeof query[0] === 'object'; return (
Array.isArray(query) && query.length > 0 && typeof query[0] === 'object'
);
} }
function getQueryAsElementArray(query: LabelQuery, defaultContainer: string): Array<Required<Element>> { function getQueryAsElementArray(
query: LabelQuery,
defaultContainer: string
): Array<Required<Element>> {
if (isElementArray(query)) { if (isElementArray(query)) {
return query.map(x => ({ return query.map(x => ({
container: x.container ?? defaultContainer, container: x.container ?? defaultContainer,
text: x.text text: x.text,
})); }));
} }
if (Array.isArray(query)) { if (Array.isArray(query)) {
return [{ return [
{
container: defaultContainer, container: defaultContainer,
text: query text: query,
}]; },
];
} }
return [{ return [
{
container: query.container ?? defaultContainer, container: query.container ?? defaultContainer,
text: query.text text: query.text,
}]; },
];
} }
export async function pageIncludesLabels(page: Page, query: LabelQuery, options: Selector) { export async function pageIncludesLabels(
page: Page,
query: LabelQuery,
options: Selector
) {
const elementQueries = getQueryAsElementArray(query, options.selector); const elementQueries = getQueryAsElementArray(query, options.selector);
const resolved = await Promise.all(elementQueries.map(async query => { const resolved = await Promise.all(
elementQueries.map(async query => {
const selector = {...options, selector: query.container}; const selector = {...options, selector: query.container};
const contents = await extractPageContents(page, selector) ?? ''; const contents = (await extractPageContents(page, selector)) ?? '';
if (!contents) { if (!contents) {
return false; return false;
@@ -47,21 +61,29 @@ export async function pageIncludesLabels(page: Page, query: LabelQuery, options:
logger.debug(contents); logger.debug(contents);
return includesLabels(contents, query.text); return includesLabels(contents, query.text);
})); })
);
return resolved.includes(true); return resolved.includes(true);
} }
export async function extractPageContents(page: Page, selector: Selector): Promise<string | null> { export async function extractPageContents(
page: Page,
selector: Selector
): Promise<string | null> {
return page.evaluate((options: Selector) => { return page.evaluate((options: Selector) => {
// eslint-disable-next-line no-undef const element: globalThis.HTMLElement | null = document.querySelector(
const element: globalThis.HTMLElement | null = document.querySelector(options.selector); options.selector
);
if (!element) { if (!element) {
return null; return null;
} }
if (options.requireVisible && !(element.offsetWidth > 0 && element.offsetHeight > 0)) { if (
options.requireVisible &&
!(element.offsetWidth > 0 && element.offsetHeight > 0)
) {
return null; return null;
} }
@@ -84,25 +106,32 @@ export async function extractPageContents(page: Page, selector: Selector): Promi
* @param domText Complete DOM of website. * @param domText Complete DOM of website.
* @param searchLabels Search labels for a match. * @param searchLabels Search labels for a match.
*/ */
export function includesLabels(domText: string, searchLabels: string[]): boolean { export function includesLabels(
domText: string,
searchLabels: string[]
): boolean {
const domTextLowerCase = domText.toLowerCase(); const domTextLowerCase = domText.toLowerCase();
return searchLabels.some(label => domTextLowerCase.includes(label.toLowerCase())); return searchLabels.some(label =>
domTextLowerCase.includes(label.toLowerCase())
);
} }
export async function cardPrice(page: Page, query: Pricing, max: number, options: Selector) { export async function getPrice(
if (!max) { page: Page,
return null; query: Pricing,
} options: Selector
): Promise<number | null> {
const selector = {...options, selector: query.container}; const selector = {...options, selector: query.container};
const cardPrice = await extractPageContents(page, selector); const priceString = await extractPageContents(page, selector);
if (cardPrice) { if (priceString) {
const priceSeperator = query.euroFormat ? /\./g : /,/g; const priceSeparator = query.euroFormat ? /\./g : /,/g;
const cardpriceNumber = Number.parseFloat(cardPrice.replace(priceSeperator, '').match(/\d+/g)!.join('.')); const price = Number.parseFloat(
priceString.replace(priceSeparator, '').match(/\d+/g)!.join('.')
);
logger.debug(`Raw card price: ${cardPrice} | Limit: ${max}`); logger.debug('received price', price);
return cardpriceNumber > max ? cardpriceNumber : null; return price;
} }
return null; return null;
+405 -86
View File
@@ -1,20 +1,146 @@
import {Browser, Page, Response} from 'puppeteer'; import {
Browser,
Page,
PageEventObj,
Request,
RespondOptions,
Response,
} from 'puppeteer';
import {Link, Store, getStores} from './model'; import {Link, Store, getStores} from './model';
import {Print, logger} from '../logger'; import {Print, logger} from '../logger';
import {Selector, cardPrice, pageIncludesLabels} from './includes-labels'; import {Selector, getPrice, pageIncludesLabels} from './includes-labels';
import {closePage, delay, getRandomUserAgent, getSleepTime, isStatusCodeInRange} from '../util'; import {
closePage,
delay,
getRandomUserAgent,
getSleepTime,
isStatusCodeInRange,
noop,
} from '../util';
import {disableBlockerInPage, enableBlockerInPage} from '../adblocker';
import {config} from '../config'; import {config} from '../config';
import {disableBlockerInPage} from '../adblocker';
import {fetchLinks} from './fetch-links'; import {fetchLinks} from './fetch-links';
import {filterStoreLink} from './filter'; import {filterStoreLink} from './filter';
import open from 'open'; import open from 'open';
import {processBackoffDelay} from './model/helpers/backoff'; import {processBackoffDelay} from './model/helpers/backoff';
import {sendNotification} from '../notification'; import {sendNotification} from '../notification';
import useProxy from '@doridian/puppeteer-page-proxy';
const inStock: Record<string, boolean> = {}; const inStock: Record<string, boolean> = {};
const linkBuilderLastRunTimes: Record<string, number> = {}; const linkBuilderLastRunTimes: Record<string, number> = {};
function nextProxy(store: Store) {
if (!store.proxyList) {
return;
}
if (store.currentProxyIndex === undefined) {
store.currentProxyIndex = 0;
}
store.currentProxyIndex++;
if (store.currentProxyIndex >= store.proxyList.length) {
store.currentProxyIndex = 0;
}
logger.info(
` [${store.name}] Next proxy index: ${store.currentProxyIndex} / Count: ${store.proxyList.length}`
);
return store.proxyList[store.currentProxyIndex];
}
async function handleLowBandwidth(request: Request) {
if (!config.browser.lowBandwidth) {
return false;
}
const typ = request.resourceType();
if (typ === 'font' || typ === 'image') {
try {
await request.abort();
} catch {
logger.debug('Failed to abort request.');
}
return true;
}
return false;
}
async function handleProxy(request: Request, proxy?: string) {
if (!proxy) {
return false;
}
try {
await useProxy(request, proxy);
} catch (error: unknown) {
logger.error('handleProxy', error);
try {
await request.abort();
} catch {
logger.debug('Failed to abort request.');
}
}
return true;
}
async function handleAdBlock(request: Request, adBlockRequestHandler: any) {
if (!adBlockRequestHandler) {
return false;
}
return new Promise(resolve => {
const continueFunc = async () => {
resolve(false);
};
const abortFunc = async () => {
try {
await request.abort();
} catch {
logger.debug('Failed to abort request.');
}
resolve(true);
};
const respondFunc = async (response: RespondOptions) => {
try {
await request.respond(response);
} catch {
logger.debug('Failed to abort request.');
}
resolve(true);
};
const requestProxy = new Proxy(request, {
get(target, prop, receiver) {
if (prop === 'continue') {
return continueFunc;
}
if (prop === 'abort') {
return abortFunc;
}
if (prop === 'respond') {
return respondFunc;
}
return Reflect.get(target, prop, receiver);
},
});
adBlockRequestHandler(requestProxy);
});
}
/** /**
* Responsible for looking up information about a each product within * Responsible for looking up information about a each product within
* a `Store`. It's important that we ignore `no-await-in-loop` here * a `Store`. It's important that we ignore `no-await-in-loop` here
@@ -28,6 +154,20 @@ async function lookup(browser: Browser, store: Store) {
return; return;
} }
if (store.linksBuilder) {
const lastRunTime = linkBuilderLastRunTimes[store.name] ?? -1;
const ttl = store.linksBuilder.ttl ?? Number.MAX_SAFE_INTEGER;
if (lastRunTime === -1 || Date.now() - lastRunTime > ttl) {
logger.info(`[${store.name}] Running linksBuilder...`);
try {
await fetchLinks(store, browser);
linkBuilderLastRunTimes[store.name] = Date.now();
} catch (error: unknown) {
logger.error(error);
}
}
}
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
for (const link of store.links) { for (const link of store.links) {
if (!filterStoreLink(link)) { if (!filterStoreLink(link)) {
@@ -39,28 +179,90 @@ async function lookup(browser: Browser, store: Store) {
continue; continue;
} }
const context = (config.browser.isIncognito ? await browser.createIncognitoBrowserContext() : browser.defaultBrowserContext()); const proxy = nextProxy(store);
const page = (config.browser.isIncognito ? await context.newPage() : await browser.newPage());
page.setDefaultNavigationTimeout(config.page.timeout);
await page.setUserAgent(getRandomUserAgent());
if (store.disableAdBlocker) { const useAdBlock = !config.browser.lowBandwidth && !store.disableAdBlocker;
try { const customContext = config.browser.isIncognito;
await disableBlockerInPage(page);
} catch (error) { const context = customContext
logger.error(error); ? await browser.createIncognitoBrowserContext()
: browser.defaultBrowserContext();
const page = await context.newPage();
await page.setRequestInterception(true);
page.setDefaultNavigationTimeout(config.page.timeout);
await page.setUserAgent(await getRandomUserAgent());
let adBlockRequestHandler: any;
let pageProxy;
if (useAdBlock) {
const onProxyFunc = (event: keyof PageEventObj, handler: any) => {
if (event !== 'request') {
page.on(event, handler);
return;
} }
adBlockRequestHandler = handler;
};
pageProxy = new Proxy(page, {
get(target, prop, receiver) {
if (prop === 'on') {
return onProxyFunc;
}
// Give dummy setRequestInterception to avoid AdBlock from messing with it
if (prop === 'setRequestInterception') {
return noop;
}
return Reflect.get(target, prop, receiver);
},
});
await enableBlockerInPage(pageProxy);
}
await page.setRequestInterception(true);
page.on('request', async request => {
if (await handleLowBandwidth(request)) {
return;
}
if (await handleAdBlock(request, adBlockRequestHandler)) {
return;
}
if (await handleProxy(request, proxy)) {
return;
}
try {
await request.continue();
} catch {
logger.debug('Failed to continue request.');
}
});
if (store.captchaDeterrent) {
await runCaptchaDeterrent(browser, store, page);
} }
let statusCode = 0; let statusCode = 0;
try { try {
statusCode = await lookupCard(browser, store, page, link); statusCode = await lookupCard(browser, store, page, link);
} catch (error) { } catch (error: unknown) {
logger.error(`✖ [${store.name}] ${link.brand} ${link.series} ${link.model} - ${error.message as string}`); logger.error(
`✖ [${store.name}] ${link.brand} ${link.series} ${link.model} - ${
(error as Error).message
}`
);
const client = await page.target().createCDPSession(); const client = await page.target().createCDPSession();
await client.send('Network.clearBrowserCookies'); await client.send('Network.clearBrowserCookies');
await client.send('Network.clearBrowserCache'); }
if (pageProxy) {
await disableBlockerInPage(pageProxy);
} }
// Must apply backoff before closing the page, e.g. if CloudFlare is // Must apply backoff before closing the page, e.g. if CloudFlare is
@@ -68,43 +270,40 @@ async function lookup(browser: Browser, store: Store) {
// before redirecting to the next page // before redirecting to the next page
await processBackoffDelay(store, link, statusCode); await processBackoffDelay(store, link, statusCode);
await closePage(page); await closePage(page);
if (config.browser.isIncognito) { if (customContext) {
await context.close(); await context.close();
} }
} }
/* eslint-enable no-await-in-loop */ /* eslint-enable no-await-in-loop */
} }
async function lookupCard(browser: Browser, store: Store, page: Page, link: Link): Promise<number> { async function lookupCard(
browser: Browser,
store: Store,
page: Page,
link: Link
): Promise<number> {
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0'; const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
const response: Response | null = await page.goto(link.url, {waitUntil: givenWaitFor}); const response: Response | null = await page.goto(link.url, {
waitUntil: givenWaitFor,
if (!response) { });
logger.debug(Print.noResponse(link, store, true));
}
const successStatusCodes = store.successStatusCodes ?? [[0, 399]]; const successStatusCodes = store.successStatusCodes ?? [[0, 399]];
const statusCode = response?.status() ?? 0; const statusCode = await handleResponse(browser, store, page, link, response);
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
if (statusCode === 429) {
logger.warn(Print.rateLimit(link, store, true));
} else {
logger.warn(Print.badStatusCode(link, store, statusCode, true));
}
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
return statusCode; return statusCode;
} }
if (await lookupCardInStock(store, page, link)) { if (await lookupCardInStock(store, page, link)) {
const givenUrl = link.cartUrl ? link.cartUrl : link.url; const givenUrl =
link.cartUrl && config.store.autoAddToCart ? link.cartUrl : link.url;
logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`); logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
if (config.browser.open) { if (config.browser.open) {
if (link.openCartAction === undefined) { await (link.openCartAction === undefined
await open(givenUrl); ? open(givenUrl)
} else { : link.openCartAction(browser));
await link.openCartAction(browser);
}
} }
sendNotification(link, store); sendNotification(link, store);
@@ -128,18 +327,93 @@ async function lookupCard(browser: Browser, store: Store, page: Page, link: Link
return statusCode; return statusCode;
} }
// eslint-disable-next-line max-params
async function handleResponse(
browser: Browser,
store: Store,
page: Page,
link: Link,
response?: Response | null,
recursionDepth = 0
) {
if (!response) {
logger.debug(Print.noResponse(link, store, true));
}
const successStatusCodes = store.successStatusCodes ?? [[0, 399]];
let statusCode = response?.status() ?? 0;
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
if (statusCode === 429) {
logger.warn(Print.rateLimit(link, store, true));
} else if (statusCode === 503) {
if (await checkIsCloudflare(store, page, link)) {
if (recursionDepth > 4) {
logger.warn(Print.recursionLimit(link, store, true));
} else {
const response: Response | null = await page.waitForNavigation({
waitUntil: 'networkidle0',
});
recursionDepth++;
statusCode = await handleResponse(
browser,
store,
page,
link,
response,
recursionDepth
);
}
} else {
logger.warn(Print.badStatusCode(link, store, statusCode, true));
}
} else {
logger.warn(Print.badStatusCode(link, store, statusCode, true));
}
}
return statusCode;
}
async function checkIsCloudflare(store: Store, page: Page, link: Link) {
const baseOptions: Selector = {
requireVisible: true,
selector: 'body',
type: 'textContent',
};
const cloudflareLabel = {
container: 'div[class="attribution"] a[rel="noopener noreferrer"]',
text: ['Cloudflare'],
};
if (await pageIncludesLabels(page, cloudflareLabel, baseOptions)) {
logger.warn(Print.cloudflare(link, store, true));
return true;
}
return false;
}
async function lookupCardInStock(store: Store, page: Page, link: Link) { async function lookupCardInStock(store: Store, page: Page, link: Link) {
const baseOptions: Selector = { const baseOptions: Selector = {
requireVisible: false, requireVisible: false,
selector: store.labels.container ?? 'body', selector: store.labels.container ?? 'body',
type: 'textContent' type: 'textContent',
}; };
if (store.labels.inStock) { if (store.labels.captcha) {
const options = {...baseOptions, requireVisible: true, type: 'outerHTML' as const}; if (await pageIncludesLabels(page, store.labels.captcha, baseOptions)) {
logger.warn(Print.captcha(link, store, true));
await delay(getSleepTime(store));
return false;
}
}
if (!await pageIncludesLabels(page, store.labels.inStock, options)) { if (store.labels.bannedSeller) {
logger.info(Print.outOfStock(link, store, true)); if (
await pageIncludesLabels(page, store.labels.bannedSeller, baseOptions)
) {
logger.warn(Print.bannedSeller(link, store, true));
return false; return false;
} }
} }
@@ -151,43 +425,48 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
} }
} }
if (store.labels.bannedSeller) {
if (await pageIncludesLabels(page, store.labels.bannedSeller, baseOptions)) {
logger.warn(Print.bannedSeller(link, store, true));
return false;
}
}
if (store.labels.maxPrice) { if (store.labels.maxPrice) {
let price; const maxPrice = config.store.maxPrice.series[link.series];
let maxPrice = 0;
switch (link.series) {
case '3070':
price = await cardPrice(page, store.labels.maxPrice, config.store.maxPrice.series['3070'], baseOptions);
maxPrice = config.store.maxPrice.series['3070'];
break;
case '3080':
price = await cardPrice(page, store.labels.maxPrice, config.store.maxPrice.series['3080'], baseOptions);
maxPrice = config.store.maxPrice.series['3080'];
break;
case '3090':
price = await cardPrice(page, store.labels.maxPrice, config.store.maxPrice.series['3090'], baseOptions);
maxPrice = config.store.maxPrice.series['3090'];
break;
default:
break;
}
if (price) { link.price = await getPrice(page, store.labels.maxPrice, baseOptions);
logger.info(Print.maxPrice(link, store, price, maxPrice, true));
if (link.price && link.price > maxPrice && maxPrice > 0) {
logger.info(Print.maxPrice(link, store, maxPrice, true));
return false; return false;
} }
} }
if (store.labels.captcha) { // Fixme: currently causing issues
if (await pageIncludesLabels(page, store.labels.captcha, baseOptions)) { // Do API inventory validation in realtime (no cache) if available
logger.warn(Print.captcha(link, store, true)); // if (
await delay(getSleepTime(store)); // store.realTimeInventoryLookup !== undefined &&
// link.itemNumber !== undefined
// ) {
// return store.realTimeInventoryLookup(link.itemNumber);
// }
if (store.labels.inStock) {
const options = {
...baseOptions,
requireVisible: true,
type: 'outerHTML' as const,
};
if (!(await pageIncludesLabels(page, store.labels.inStock, options))) {
logger.info(Print.outOfStock(link, store, true));
return false;
}
}
if (link.labels?.inStock) {
const options = {
...baseOptions,
requireVisible: true,
type: 'outerHTML' as const,
};
if (!(await pageIncludesLabels(page, link.labels.inStock, options))) {
logger.info(Print.outOfStock(link, store, true));
return false; return false;
} }
} }
@@ -195,29 +474,69 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
return true; return true;
} }
async function runCaptchaDeterrent(browser: Browser, store: Store, page: Page) {
const successStatusCodes = store.successStatusCodes ?? [[0, 399]];
let statusCode = 0;
let deterrentLinks: string[] = [];
logger.debug(`[${store.name}] Navigating to random anti-captcha page...`);
if (store.captchaDeterrent?.hardLinks?.length) {
deterrentLinks = deterrentLinks.concat(store.captchaDeterrent.hardLinks);
}
if (store.captchaDeterrent?.searchUrl) {
if (store.captchaDeterrent.searchTerms) {
store.captchaDeterrent.searchTerms.forEach(element =>
deterrentLinks.push(
store.captchaDeterrent?.searchUrl
? store.captchaDeterrent.searchUrl.replace('%%s', element)
: ''
)
);
}
}
if (deterrentLinks.length > 0) {
const link: Link = {
brand: 'captcha-deterrent',
model: 'captcha-deterrent',
series: 'captcha-deterrent',
url: deterrentLinks[Math.floor(Math.random() * deterrentLinks.length)],
};
logger.debug(`Selected captcha-deterrent link: ${link.url}`);
try {
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
const response: Response | null = await page.goto(link.url, {
waitUntil: givenWaitFor,
});
statusCode = await handleResponse(browser, store, page, link, response);
setTimeout(() => {
// Do nothing
}, 3000);
} catch (error: unknown) {
logger.error(error);
}
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
logger.warn(
`✖ [${store.name}] - Failed to navigate to anti-captcha target: ${link.url}`
);
}
}
}
export async function tryLookupAndLoop(browser: Browser, store: Store) { export async function tryLookupAndLoop(browser: Browser, store: Store) {
if (!browser.isConnected()) { if (!browser.isConnected()) {
logger.debug(`[${store.name}] Ending this loop as browser is disposed...`); logger.debug(`[${store.name}] Ending this loop as browser is disposed...`);
return; return;
} }
if (store.linksBuilder) {
const lastRunTime = linkBuilderLastRunTimes[store.name] ?? -1;
const ttl = store.linksBuilder.ttl ?? Number.MAX_SAFE_INTEGER;
if (lastRunTime === -1 || (Date.now() - lastRunTime) > ttl) {
try {
await fetchLinks(store, browser);
linkBuilderLastRunTimes[store.name] = Date.now();
} catch (error) {
logger.error(error.message);
}
}
}
logger.debug(`[${store.name}] Starting lookup...`); logger.debug(`[${store.name}] Starting lookup...`);
try { try {
await lookup(browser, store); await lookup(browser, store);
} catch (error) { } catch (error: unknown) {
logger.error(error); logger.error(error);
} }
+234
View File
@@ -0,0 +1,234 @@
import {Store} from './store';
export const AComPC: Store = {
currency: '€',
labels: {
inStock: {
container: '.filial_stock',
text: ['lagernd', 'im Zulauf'],
},
maxPrice: {
container: '.price',
euroFormat: true,
},
outOfStock: [
{
container: '.filial_stock',
text: ['nicht lieferbar'],
},
],
},
links: [
{
brand: 'asus',
model: 'strix',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-ROG-STRIX-RTX3080-10G-GAMING-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-2-x-HDMI-3-x-DisplayPort.html',
},
{
brand: 'asus',
model: 'strix oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-ROG-STRIX-RTX3080-O10G-GAMING-OC-Edition-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-2-x-HDMI-3-x-DisplayPort.html',
},
{
brand: 'asus',
model: 'tuf',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-TUF-Gaming-GeForce-RTX-3080-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-TUF-Gaming-GeForce-RTX-3080-OC-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'aorus master',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-AORUS-GeForce-RTX-3080-MASTER-10G-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-3-x-DisplayPort-3-x-HDMI.html',
},
{
brand: 'gigabyte',
model: 'aorus xtreme',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-AORUS-GeForce-RTX-3080-XTREME-10G-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-3-x-DisplayPort-3-x-HDMI.html',
},
{
brand: 'gigabyte',
model: 'eagle oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3080-Eagle-OC-10G-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'eagle',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3080-Eagle-10G-Grafikkarte-10.240-MB.html',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3080-GAMING-OC-10G-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'vision oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3080-Vision-OC-10G-Grafikkarten-GF-RTX-3080-10GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DP-weiss.html',
},
{
brand: 'inno3d',
model: 'twin x2 oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Inno3D-GeForce-RTX-3080-Twin-X2-OC-Grafikkarten-GF-RTX-3080-10-GB-GDDR6-PCIe-4.0-x16-HDMI-3x-DisplayPort.html',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/MSI-GeForce-RTX-3080-Gaming-X-Trio-10G-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-HDMI-3x-DisplayPort.html',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/MSI-GeForce-RTX-3080-Ventus-3X-10G-OC-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-x16-HDMI-3x-DisplayPort.html',
},
{
brand: 'zotac',
model: 'amp holo',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ZOTAC-GAMING-GeForce-RTX-3080-AMP-Holo-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-HDMI-3-x-DisplayPort.html',
},
{
brand: 'zotac',
model: 'trinity oc',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ZOTAC-GAMING-GeForce-RTX-3080-Trinity-OC-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-HDMI-3-x-DisplayPort.html',
},
{
brand: 'zotac',
model: 'trinity',
series: '3080',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ZOTAC-GAMING-GeForce-RTX-3080-Trinity-Grafikkarten-GF-RTX-3080-10-GB-GDDR6X-PCIe-4.0-HDMI-3x-DisplayPort.html',
},
{
brand: 'asus',
model: 'strix',
series: '3090',
url:
'https://www.acom-pc.de/Peripherie-Zubehoer/noch-nicht-kategorisierte-Artikel/ASUS-ROG-Strix-GeForce-RTX-3090-ROG-STRIX-RTX3090-24G-GAMING-24GB-GDDR6X-2x-HDMI-3x-DP-90YV0F90-M0NM00-.html',
},
{
brand: 'asus',
model: 'strix oc',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-ROG-STRIX-RTX3090-O24G-GAMING-OC-Edition-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-2-x-HDMI-3-x-DisplayPort.html',
},
{
brand: 'asus',
model: 'tuf',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-TUF-Gaming-GeForce-RTX-3090-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ASUS-TUF-Gaming-GeForce-RTX-3090-OC-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'aorus master',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-Aorus-GeForce-RTX-3090-Master-24G-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'eagle oc',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3090-Eagle-OC-24G-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/Gigabyte-GeForce-RTX-3090-Gaming-OC-24G-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-2x-HDMI-3x-DisplayPort.html',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/MSI-RTX-3090-GAMING-X-TRIO-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-HDMI-3x-DisplayPort.html',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/MSI-GeForce-RTX-3090-Ventus-3X-24G-OC-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-x16-HDMI-3x-DisplayPort.html',
},
{
brand: 'zotac',
model: 'trinity',
series: '3090',
url:
'https://www.acom-pc.de/Hardware-Software/Grafikkarten-Zubehoer/Grafikkarten-NVIDIA-PCI-Express/ZOTAC-GAMING-GeForce-RTX-3090-Trinity-Grafikkarten-GF-RTX-3090-24-GB-GDDR6X-PCIe-4.0-HDMI-3x-DisplayPort.html',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url:
'https://www.acom-pc.de/Hardware-Software/CPU-Prozessor-/-CPU-Kuehler-Zubehoer/AMD-CPU/AMD-CPU-Socket-AM4/AMD-RYZEN-5-5600X-4.60GHZ-6-CORE-SKT-AM4-35MB-65W-PIB.html',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url:
'https://www.acom-pc.de/Hardware-Software/CPU-Prozessor-/-CPU-Kuehler-Zubehoer/AMD-CPU/AMD-CPU-Socket-AM4/AMD-RYZEN-7-5800X-4.70GHZ-8-CORE-SKT-AM4-36MB-105W-WOF.html',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url:
'https://www.acom-pc.de/Hardware-Software/CPU-Prozessor-/-CPU-Kuehler-Zubehoer/AMD-CPU/AMD-CPU-Socket-AM4/AMD-Ryzen-9-5900X-AMD-Ryzen-9-Socket-AM4-PC-7nm-AMD-3-7-GHz-AM4.html',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url:
'https://www.acom-pc.de/Hardware-Software/CPU-Prozessor-/-CPU-Kuehler-Zubehoer/AMD-CPU/AMD-CPU-Socket-AM4/AMD-RYZEN-9-5950X-4.90GHZ-16-CORE-SKT-AM4-72MB-105W-WOF.html',
},
],
name: 'acompc',
};
+29 -28
View File
@@ -1,129 +1,130 @@
import {Store} from './store'; import {Store} from './store';
export const Adorama: Store = { export const Adorama: Store = {
currency: '$',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['please verify you are a human'] text: ['please verify you are a human'],
}, },
inStock: { inStock: {
container: '.buy-section.purchase', container: '.buy-section.purchase',
text: ['add to cart'] text: ['add to cart'],
}, },
maxPrice: { maxPrice: {
container: '.your-price', container: '.your-price',
euroFormat: false euroFormat: false,
} },
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.adorama.com/ev08gp43067k.html' url: 'https://www.adorama.com/ev08gp43067k.html',
}, },
{ {
brand: 'pny', brand: 'pny',
model: 'xlr8', model: 'xlr8 revel',
series: '3080', series: '3080',
url: 'https://www.adorama.com/pnv301tfxmpb.html' url: 'https://www.adorama.com/pnv301tfxmpb.html',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.adorama.com/msig380gxt1.html' url: 'https://www.adorama.com/msig380gxt1.html',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.adorama.com/ev10g53897kr.html' url: 'https://www.adorama.com/ev10g53897kr.html',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.adorama.com/ev10g53885kr.html' url: 'https://www.adorama.com/ev10g53885kr.html',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.adorama.com/ev10g53895kr.html' url: 'https://www.adorama.com/ev10g53895kr.html',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.adorama.com/ev10g53883kr.html' url: 'https://www.adorama.com/ev10g53883kr.html',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.adorama.com/ev10g53881kr.html' url: 'https://www.adorama.com/ev10g53881kr.html',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.adorama.com/msig38v3x10c.html' url: 'https://www.adorama.com/msig38v3x10c.html',
}, },
{ {
brand: 'pny', brand: 'pny',
model: 'xlr8 rgb', model: 'xlr8 revel',
series: '3080', series: '3080',
url: 'https://www.adorama.com/png30801tfxb.html' url: 'https://www.adorama.com/png30801tfxb.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.adorama.com/asrx3080o10g.html' url: 'https://www.adorama.com/asrx3080o10g.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.adorama.com/astr3080o10g.html' url: 'https://www.adorama.com/astr3080o10g.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.adorama.com/astrx308010g.html' url: 'https://www.adorama.com/astrx308010g.html',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'gaming x trio', model: 'gaming x trio',
series: '3090', series: '3090',
url: 'https://www.adorama.com/msig390gxt24.html' url: 'https://www.adorama.com/msig390gxt24.html',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3090', series: '3090',
url: 'https://www.adorama.com/msig39v3x24c.html' url: 'https://www.adorama.com/msig39v3x24c.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf', model: 'tuf',
series: '3090', series: '3090',
url: 'https://www.adorama.com/asrtx309024g.html' url: 'https://www.adorama.com/asrtx309024g.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.adorama.com/ast3090o24g.html' url: 'https://www.adorama.com/ast3090o24g.html',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', model: 'strix oc',
series: '3090', series: '3090',
url: 'https://www.adorama.com/asrx3090o24g.html' url: 'https://www.adorama.com/asrx3090o24g.html',
} },
], ],
name: 'adorama' name: 'adorama',
}; };
+329
View File
@@ -0,0 +1,329 @@
import {Store} from './store';
export const Akinformatica: Store = {
currency: '€',
labels: {
inStock: [
{
container: '#dispOnLine .available',
text: ['Disponibile Online'],
},
{
container: '#addCartLinkButton',
text: ['Aggiungi al carrello'],
},
],
maxPrice: {
container: '#PrezzoListinoIvatoLabel',
euroFormat: true,
},
outOfStock: [
{
container: '#dispOnLine .available .disabled',
text: ['Disponibile Online'],
},
{
container: '#preOrderPanel > label',
text: ['PRE-ORDINI APERTI'],
},
],
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url:
'https://shop.akinformatica.it/catalogo/adata-xpg/mouse-gaming-adata-xpg-primer---wired--rgb_4710273777139.aspx',
},
{
brand: 'palit',
model: 'gaming pro',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-palit-geforce-rtx3070-gamingpro-oc-8gb-gddr6x_4710562242089.aspx',
},
{
brand: 'zotac',
model: 'twin edge',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-zotac-gaming-geforce-rtx-3070-twin-edge-8g_4895173622472.aspx',
},
{
brand: 'msi',
model: 'ventus 2x oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-msi-geforce-rtx-3070-ventus-2x-oc-8g_4719072763091.aspx',
},
{
brand: 'asus',
model: 'dual',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-asus-geforce-rtx-3070-dual-o8g-8g_4718017927864.aspx',
},
{
brand: 'gigabyte',
model: 'eagle',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-gigabyte-geforce-rtx-3070-eagle-8gb_4719331307738.aspx',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-msi-geforce-rtx-3070-ventus-3x-oc-8g_4719072763084.aspx',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-msi-geforce-rtx-3070-gaming-x-trio-8g_4719072763053.aspx',
},
{
brand: 'zotac',
model: 'twin edge oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-zotac-gaming-geforce-rtx-3070-twin-edge-oc-8g_4895173622489.aspx',
},
{
brand: 'gigabyte',
model: 'eagle oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-gigabyte-geforce-rtx-3070-eagle-oc-8gb_4719331307677.aspx',
},
{
brand: 'asus',
model: 'tuf',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-asus-geforce-rtx-3070-tuf-o8g-8g_4718017948678.aspx',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-gigabyte-geforce-rtx-3070-gaming-oc-8gb_4719331307691.aspx',
},
{
brand: 'asus',
model: 'strix oc',
series: '3070',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3070/vga-asus-geforce-rtx-3070-rog-strix-gaming-oc-8g_4718017938150.aspx',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-msi-geforce-rtx-3090-gaming-x-trio-24g_4719072762506.aspx',
},
{
brand: 'zotac',
model: 'trinity',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-zotac-geforce-rtx-3090-trinity-24g_4895173622427.aspx',
},
{
brand: 'msi',
model: 'suprim x',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-msi-geforce-rtx-3090-suprim-x-24g_4719072762490.aspx',
},
{
brand: 'pny',
model: 'xlr8 epic x',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-pny-geforce-rtx-3090-epic-x-xlr8-gaming-24g_0751492639536.aspx',
},
{
brand: 'msi',
model: 'ventus 3x',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-msi-geforce-rtx-3090-ventus-3x-24g-oc--consegne-da-marzo_4719072762476.aspx',
},
{
brand: 'palit',
model: 'gamerock',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-palit-geforce-rtx3090-gamerock-24gb-gddr6x_4710562242041.aspx',
},
{
brand: 'palit',
model: 'gaming pro',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-palit-geforce-rtx3090-gamingpro-24gb-gddr6x_4710562241969.aspx',
},
{
brand: 'palit',
model: 'gamerock oc',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-palit-geforce-rtx3090-gamerock-oc-24gb-gddr6x_4710562242065.aspx',
},
{
brand: 'palit',
model: 'gaming pro oc',
series: '3090',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3090/vga-palit-geforce-rtx3090-gamingpro-oc-24gb-gddr6x_4710562242027.aspx',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url:
'https://shop.akinformatica.it/catalogo/amd-am4/cpu-amd-ryzen-5-5600x---6-core--max-boost-4-60-ghz--socket-am4_0730143312042.aspx',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url:
'https://shop.akinformatica.it/catalogo/amd-am4/cpu-amd-ryzen-7-5800x---8-core--max-boost-4-70-ghz--socket-am4_0730143312714.aspx',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url:
'https://shop.akinformatica.it/catalogo/amd-am4/cpu-amd-ryzen-9-5950x---16-core--max-boost-4-90-ghz--socket-am4_0730143312745.aspx',
},
{
brand: 'sapphire',
model: 'nitro+ se',
series: 'rx6800',
url:
'https://shop.akinformatica.it/catalogo/amd-rx-6800-6800-xt/vga-sapphire-radeon-rx-6800-xt-nitro--oc-se-16g_4895106289901.aspx',
},
{
brand: 'sapphire',
model: 'nitro+',
series: 'rx6800',
url:
'https://shop.akinformatica.it/catalogo/amd-rx-6800-6800-xt/vga-sapphire-radeon-rx-6800-xt-nitro--16g_4895106289925.aspx',
},
{
brand: 'sapphire',
model: 'amd reference',
series: 'rx6900xt',
url:
'https://shop.akinformatica.it/catalogo/amd-rx-6900-xt/vga-sapphire-radeon-rx-6900-xt-16g_4895106290136.aspx',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-msi-geforce-rtx-3080-ventus-3x-10g-oc--consegne-da-marzo_4719072762520.aspx',
},
{
brand: 'zotac',
model: 'trinity',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-zotac-geforce-rtx-3080-trinity-10g_4895173622403.aspx',
},
{
brand: 'asus',
model: 'strix oc',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-asus-geforce-rtx-3080-rog-strix-gaming-oc-10g_4718017928786.aspx',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-msi-geforce-rtx-3080-gaming-x-trio-10g_4719072762544.aspx',
},
{
brand: 'asus',
model: 'strix',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-asus-geforce-rtx-3080-rog-strix-gaming-10g_4718017909150.aspx',
},
{
brand: 'pny',
model: 'xlr8 epic x',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-pny-geforce-rtx-3080-epic-x-xlr8-gaming-10g_0751492639567.aspx',
},
{
brand: 'pny',
model: 'xlr8 epic x',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-pny-geforce-rtx-3080-epic-x-xlr8-gaming-10g_0751492639550.aspx',
},
{
brand: 'palit',
model: 'gaming pro oc',
series: '3080',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3080/vga-palit-geforce-rtx3080-gamingpro-oc-10gb-gddr6x_4710562242003.aspx',
},
{
brand: 'msi',
model: 'ventus 2x oc',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-msi-geforce-rtx-3060ti-ventus-2x-oc-8g-_4719072763121.aspx',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-msi-geforce-rtx-3060ti-gaming-x-trio-8g-_4719072763145.aspx',
},
{
brand: 'palit',
model: 'dual oc',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-palit-geforce-rtx-3060ti-dual-oc-8g-gddr6-256bit-3xdp--hdmi-_4710562242287.aspx',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-msi-geforce-rtx-3060ti-ventus-3x-oc-8g_4719072763152.aspx',
},
{
brand: 'zotac',
model: 'twin edge',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-zotac-gaming-geforce-rtx-3060ti-twin-edge-8g_4895173622502.aspx',
},
{
brand: 'zotac',
model: 'twin edge oc',
series: '3060ti',
url:
'https://shop.akinformatica.it/catalogo/nvidia-rtx-3060ti/vga-zotac-gaming-geforce-rtx-3060ti-twin-edge-oc-8g_4895173622519.aspx',
},
],
name: 'akinformatica',
successStatusCodes: [[0, 399], 404],
};
+64
View File
@@ -0,0 +1,64 @@
import {Store} from './store';
export const Allneeds: Store = {
backoffStatusCodes: [403, 429],
currency: '$',
labels: {
inStock: {
container: '.amstockstatus',
text: ['In Stock'],
},
maxPrice: {
container: 'span.price',
euroFormat: false,
},
outOfStock: {
container: '.amstockstatus',
text: ['sold out'],
},
},
links: [
{
brand: 'asus',
model: 'strix oc white',
series: '3080',
url:
'https://allneeds.com.au/asus-geforce-rtx-3080-rog-strix-gaming-oc-10gb-video-card-white-edition-limited-edition',
},
{
brand: 'sapphire',
model: 'nitro+',
series: 'rx6900xt',
url:
'https://allneeds.com.au/sapphire-nitro-radeon-rx-6900-xt-16gb-video-card-11308-01-20g',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url:
'https://allneeds.com.au/amd-ryzen-9-5950x-processor-100-100000059wof',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url:
'https://allneeds.com.au/amd-ryzen-9-5900x-processor-100-100000061wof',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url: 'https://allneeds.com.au/amd-ryzen-7-5800x-processor',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url:
'https://allneeds.com.au/amd-ryzen-5-5600x-with-wraith-stealth-100-100000065box',
},
],
name: 'allneeds',
};
+41 -41
View File
@@ -1,172 +1,172 @@
import {Store} from './store'; import {Store} from './store';
export const AlternateNL: Store = { export const AlternateNL: Store = {
currency: '€',
labels: { labels: {
inStock: { inStock: {
container: '.stockStatus', container: '.stockStatus',
text: ['Direct leverbaar'] text: ['Direct leverbaar'],
}, },
maxPrice: { maxPrice: {
container: 'div.price > span', container: 'div.price > span',
euroFormat: true euroFormat: true,
}, },
outOfStock: { outOfStock: {
container: '.stockStatus', container: '.stockStatus',
text: ['Levertermijn onbekend', 'pre-order'] text: ['Levertermijn onbekend', 'pre-order'],
} },
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.alternate.nl/product/1516616' url: 'https://www.alternate.nl/product/1516616',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672756' url: 'https://www.alternate.nl/product/1672756',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672345' url: 'https://www.alternate.nl/product/1672345',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf gaming', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672251' url: 'https://www.alternate.nl/product/1672251',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672753' url: 'https://www.alternate.nl/product/1672753',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672343' url: 'https://www.alternate.nl/product/1672343',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf oc gaming', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672634' url: 'https://www.alternate.nl/product/1672634',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc gaming', model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672867' url: 'https://www.alternate.nl/product/1672867',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 black gaming', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673512' url: 'https://www.alternate.nl/product/1673512',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672612' url: 'https://www.alternate.nl/product/1672612',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 ultra gaming', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1674164' url: 'https://www.alternate.nl/product/1674164',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix gaming', model: 'strix',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1672868' url: 'https://www.alternate.nl/product/1672868',
}, },
{ {
brand: 'palit', brand: 'palit',
model: 'gaming pro oc', model: 'gaming pro oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673431' url: 'https://www.alternate.nl/product/1673431',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'trinity oc', model: 'trinity oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1677989' url: 'https://www.alternate.nl/product/1677989',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'vision oc', model: 'vision oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1681134' url: 'https://www.alternate.nl/product/1681134',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 gaming', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673520' url: 'https://www.alternate.nl/product/1673520',
}, },
{ {
brand: 'gainward', brand: 'gainward',
model: 'phoenix gs', model: 'phoenix gs',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673442' url: 'https://www.alternate.nl/product/1673442',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x3', model: 'ichill x3',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673136' url: 'https://www.alternate.nl/product/1673136',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3 ultra gaming', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673524' url: 'https://www.alternate.nl/product/1673524',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'aorus master', model: 'aorus master',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1680168' url: 'https://www.alternate.nl/product/1680168',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3 gaming', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673517' url: 'https://www.alternate.nl/product/1673517',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'amp holo', model: 'amp holo',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1677985' url: 'https://www.alternate.nl/product/1677985',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'amp extreme holo', model: 'amp extreme holo',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1677982' url: 'https://www.alternate.nl/product/1677982',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'twin x2 oc', model: 'twin x2 oc',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673137' url: 'https://www.alternate.nl/product/1673137',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x4', model: 'ichill x4',
series: '3080', series: '3080',
url: 'https://www.alternate.nl/product/1673134' url: 'https://www.alternate.nl/product/1673134',
} },
], ],
name: 'alternate-nl' name: 'alternate-nl',
}; };
+175 -61
View File
@@ -1,321 +1,435 @@
import {Store} from './store'; import {Store} from './store';
export const Alternate: Store = { export const Alternate: Store = {
currency: '€',
labels: { labels: {
inStock: { inStock: {
container: '.stockStatus', container: '.stockStatus',
text: ['auf lager', 'ware neu eingetroffen', 'in kürze versandfertig', 'ware im zulauf'] text: [
'auf lager',
'ware neu eingetroffen',
'in kürze versandfertig',
'ware im zulauf',
],
}, },
maxPrice: { maxPrice: {
container: 'div.price > span', container: 'div.price > span',
euroFormat: true euroFormat: true,
}, },
outOfStock: { outOfStock: [
{
container: '.stockStatus', container: '.stockStatus',
text: ['liefertermin unbekannt'] text: ['liefertermin unbekannt'],
} },
{
container: '.stockStatus',
text: ['Artikel kann nicht gekauft werden'],
},
],
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.alternate.de/product/1516616' url: 'https://www.alternate.de/product/1662088',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix', model: 'strix',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672868' url: 'https://www.alternate.de/product/1672868',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672867' url: 'https://www.alternate.de/product/1672867',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672251' url: 'https://www.alternate.de/product/1672251',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672634' url: 'https://www.alternate.de/product/1672634',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673517' url: 'https://www.alternate.de/product/1673517',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673524' url: 'https://www.alternate.de/product/1673524',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673512' url: 'https://www.alternate.de/product/1673512',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673520' url: 'https://www.alternate.de/product/1673520',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1674164' url: 'https://www.alternate.de/product/1674164',
}, },
{ {
brand: 'gainward', brand: 'gainward',
model: 'phantom gs', model: 'phantom gs',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1688597' url: 'https://www.alternate.de/product/1688597',
}, },
{ {
brand: 'gainward', brand: 'gainward',
model: 'phoenix gs', model: 'phoenix gs',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673442' url: 'https://www.alternate.de/product/1673442',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'aorus master', model: 'aorus master',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1680168' url: 'https://www.alternate.de/product/1680168',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'aorus xtreme', model: 'aorus xtreme',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1680168' url: 'https://www.alternate.de/product/1680168',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672756' url: 'https://www.alternate.de/product/1672756',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672753' url: 'https://www.alternate.de/product/1672753',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'vision oc', model: 'vision oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1681134' url: 'https://www.alternate.de/product/1681134',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x3', model: 'ichill x3',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673136' url: 'https://www.alternate.de/product/1673136',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x4', model: 'ichill x4',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673134' url: 'https://www.alternate.de/product/1673134',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'twin x2 oc', model: 'twin x2 oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673137' url: 'https://www.alternate.de/product/1673137',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672343' url: 'https://www.alternate.de/product/1672343',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672345' url: 'https://www.alternate.de/product/1672345',
}, },
{ {
brand: 'palit', brand: 'palit',
model: 'gamerock oc', model: 'gamerock oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1688594' url: 'https://www.alternate.de/product/1688594',
}, },
{ {
brand: 'palit', brand: 'palit',
model: 'gaming pro oc', model: 'gaming pro oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1673431' url: 'https://www.alternate.de/product/1673431',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'amp extreme holo', model: 'amp extreme holo',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1677982' url: 'https://www.alternate.de/product/1677982',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'amp holo', model: 'amp holo',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1677985' url: 'https://www.alternate.de/product/1677985',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'trinity oc', model: 'trinity oc',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1677989' url: 'https://www.alternate.de/product/1677989',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.alternate.de/product/1672612' url: 'https://www.alternate.de/product/1672612',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix', model: 'strix',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672870' url: 'https://www.alternate.de/product/1672870',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', model: 'strix oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672872' url: 'https://www.alternate.de/product/1672872',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf', model: 'tuf',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672259' url: 'https://www.alternate.de/product/1672259',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672629' url: 'https://www.alternate.de/product/1672629',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3', model: 'ftw3',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673530' url: 'https://www.alternate.de/product/1673530',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673531' url: 'https://www.alternate.de/product/1673531',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 black', model: 'xc3 black',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673521' url: 'https://www.alternate.de/product/1673521',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3', model: 'xc3',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673525' url: 'https://www.alternate.de/product/1673525',
}, },
{ {
brand: 'evga', brand: 'evga',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673529' url: 'https://www.alternate.de/product/1673529',
}, },
{ {
brand: 'gainward', brand: 'gainward',
model: 'phoenix gs', model: 'phoenix gs',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673440' url: 'https://www.alternate.de/product/1673440',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'aorus xtreme', model: 'aorus xtreme',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1680670' url: 'https://www.alternate.de/product/1680670',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'aorus master', model: 'aorus master',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1687793' url: 'https://www.alternate.de/product/1687793',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'eagle oc', model: 'eagle oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672744' url: 'https://www.alternate.de/product/1672744',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'gaming oc', model: 'gaming oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672749' url: 'https://www.alternate.de/product/1672749',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
model: 'turbo', model: 'turbo',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1687703' url: 'https://www.alternate.de/product/1687703',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'gaming x3', model: 'gaming x3',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673131' url: 'https://www.alternate.de/product/1673131',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x3', model: 'ichill x3',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673135' url: 'https://www.alternate.de/product/1673135',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
model: 'ichill x4', model: 'ichill x4',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673129' url: 'https://www.alternate.de/product/1673129',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'gaming x trio', model: 'gaming x trio',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672341' url: 'https://www.alternate.de/product/1672341',
}, },
{ {
brand: 'msi', brand: 'msi',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672346' url: 'https://www.alternate.de/product/1672346',
}, },
{ {
brand: 'palit', brand: 'palit',
model: 'gaming pro oc', model: 'gaming pro oc',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1673434' url: 'https://www.alternate.de/product/1673434',
}, },
{ {
brand: 'zotac', brand: 'zotac',
model: 'trinity', model: 'trinity',
series: '3090', series: '3090',
url: 'https://www.alternate.de/product/1672611' url: 'https://www.alternate.de/product/1672611',
} },
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.alternate.de/product/1685588',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.alternate.de/product/1685585',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.alternate.de/product/1685590',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.alternate.de/product/1685584',
},
{
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.alternate.de/product/1651220',
},
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.alternate.de/product/1651221',
},
{
brand: 'xfx',
model: 'merc',
series: 'rx6800xt',
url: 'https://www.alternate.de/product/1698792',
},
{
brand: 'sapphire',
model: 'nitro oc se',
series: 'rx6800xt',
url: 'https://www.alternate.de/product/1696478',
},
{
brand: 'sapphire',
model: 'nitro oc',
series: 'rx6800xt',
url: 'https://www.alternate.de/product/1696482',
},
{
brand: 'asus',
model: 'strix lc',
series: 'rx6800xt',
url: 'https://www.alternate.de/product/1695392',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: 'rx6800xt',
url: 'https://www.alternate.de/product/1697044',
},
{
brand: 'asus',
model: 'tuf oc',
series: 'rx6900xt',
url: 'https://www.alternate.de/product/1702773',
},
{
brand: 'msi',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.alternate.de/product/1700508',
},
{
brand: 'xfx',
model: 'merc',
series: 'rx6900xt',
url: 'https://www.alternate.de/product/1704614',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.alternate.de/product/1675115',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.alternate.de/product/1675117',
},
{
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.alternate.de/product/1676874',
},
], ],
name: 'alternate' name: 'alternate',
}; };
+184 -26
View File
@@ -1,135 +1,293 @@
import {Store} from './store'; import {Store} from './store';
export const AmazonCa: Store = { export const AmazonCa: Store = {
currency: '$',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['enter the characters you see below'] text: ['enter the characters you see below'],
}, },
inStock: { inStock: {
container: '#desktop_buybox', container: '#desktop_buybox',
text: ['add to cart'] text: ['add to cart'],
}, },
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]', container: '#priceblock_ourprice',
euroFormat: false },
}
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B07PBLD2MX&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.ca/dp/B07PBLD2MX' url: 'https://www.amazon.ca/dp/B07PBLD2MX',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming x trio',
series: '3070',
url: 'https://www.amazon.ca/dp/B08KWN2LZG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.ca/dp/B08KWLMZV4',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
model: 'xc3',
series: '3070',
url: 'https://www.amazon.ca/dp/B08LW46GH2',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.ca/dp/B08L8L71SM',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3070',
url: 'https://www.amazon.ca/dp/B08L8L9TCZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR7SV3M' url: 'https://www.amazon.ca/dp/B08HR7SV3M',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR5SXPS' url: 'https://www.amazon.ca/dp/B08HR5SXPS',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR3DPGW' url: 'https://www.amazon.ca/dp/B08HR3DPGW',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR3Y5GQ' url: 'https://www.amazon.ca/dp/B08HR3Y5GQ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR55YB5' url: 'https://www.amazon.ca/dp/B08HR55YB5',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR4RJ3Q' url: 'https://www.amazon.ca/dp/B08HR4RJ3Q',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HR6FMF3' url: 'https://www.amazon.ca/dp/B08HR6FMF3',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HJTH61J' url: 'https://www.amazon.ca/dp/B08HJTH61J',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HJS2JLJ' url: 'https://www.amazon.ca/dp/B08HJS2JLJ',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HHDP9DW' url: 'https://www.amazon.ca/dp/B08HHDP9DW',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HH5WF97' url: 'https://www.amazon.ca/dp/B08HH5WF97',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.amazon.ca/dp/B08HJNKT3P' url: 'https://www.amazon.ca/dp/B08HJNKT3P',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HJQ182D' url: 'https://www.amazon.ca/dp/B08HJQ182D',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HR9D2JS' url: 'https://www.amazon.ca/dp/B08HR9D2JS',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HJRF2CN' url: 'https://www.amazon.ca/dp/B08HJRF2CN',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HJPDJTY' url: 'https://www.amazon.ca/dp/B08HJPDJTY',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HJGNJ81' url: 'https://www.amazon.ca/dp/B08HJGNJ81',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.amazon.ca/dp/B08HJLLF7G' url: 'https://www.amazon.ca/dp/B08HJLLF7G',
} },
{
brand: 'amd',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.ca/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.ca/dp/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.ca/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.ca/dp/B0815Y8J9N',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08GSC5D9G&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.ca/dp/B08GSC5D9G',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08GS1N24H&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.ca/dp/B08GS1N24H',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08H75RTZ8&Quantity.1=1',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.ca/dp/B08H75RTZ8',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08G9J44ZN&Quantity.1=1',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.ca/dp/B08G9J44ZN',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08NX14LV1&Quantity.1=1',
model: 'merc',
series: 'rx6800xt',
url: 'https://www.amazon.ca/dp/B08NX14LV1',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08PQ585CX&Quantity.1=1',
model: 'pulse',
series: 'rx6800xt',
url: 'https://www.amazon.ca/dp/B08PQ585CX',
},
], ],
name: 'amazon-ca' name: 'amazon-ca',
}; };
+64
View File
@@ -0,0 +1,64 @@
import {Store} from './store';
export const AmazonDeWarehouse: Store = {
backoffStatusCodes: [403, 429, 503],
currency: '€',
labels: {
captcha: {
container: 'body',
text: [
'geben sie die unten angezeigten zeichen ein',
'geben sie die zeichen unten ein',
],
},
inStock: {
container: '#a-autoid-0-announce',
text: ['In den Einkaufswagen'],
},
maxPrice: {
container: '.olpOfferPrice',
euroFormat: true,
},
outOfStock: [
{
container: '.a-size-medium',
text: [
'Derzeit gibt es keine Verkäufer, die diesen Artikel an Ihren Standort liefern können',
],
},
],
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amazon.de/gp/offer-listing/B07PW9VBK5',
},
{
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.de/gp/offer-listing/B08H93ZRK9',
},
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.de/gp/offer-listing/B08H98GVK8',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.de/gp/offer-listing/B087VM5XC6',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.de/gp/offer-listing/B08H93ZRLL',
},
],
name: 'amazon-de-warehouse',
};
+353 -51
View File
@@ -2,255 +2,557 @@ import {Store} from './store';
export const AmazonDe: Store = { export const AmazonDe: Store = {
backoffStatusCodes: [403, 429, 503], backoffStatusCodes: [403, 429, 503],
currency: '€',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['geben sie die unten angezeigten zeichen ein', 'geben sie die zeichen unten ein'] text: [
'geben sie die unten angezeigten zeichen ein',
'geben sie die zeichen unten ein',
],
}, },
inStock: { inStock: {
container: '#desktop_buybox', container: '#add-to-cart-button',
text: ['in den einkaufswagen'] text: ['in den einkaufswagen'],
}, },
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]', container: '#priceblock_ourprice',
euroFormat: true euroFormat: true,
} },
outOfStock: [
{
container: '#availability',
text: ['Derzeit nicht verfügbar'],
},
],
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B07PW9VBK5&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.de/dp/B083JX52VG/' url: 'https://www.amazon.de/dp/B07PW9VBK5',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix', cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN7VVLJ&Quantity.1=1',
model: 'strix',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HN7VVLJ' url: 'https://www.amazon.de/dp/B08HN7VVLJ',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN6KYS3&Quantity.1=1',
model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HN6KYS3' url: 'https://www.amazon.de/dp/B08HN6KYS3',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN37VQK&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HN37VQK' url: 'https://www.amazon.de/dp/B08HN37VQK',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN4DSTC&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HN4DSTC' url: 'https://www.amazon.de/dp/B08HN4DSTC',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGBYWQ6&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HGBYWQ6' url: 'https://www.amazon.de/dp/B08HGBYWQ6',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGYXP4C&Quantity.1=1',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HGYXP4C' url: 'https://www.amazon.de/dp/B08HGYXP4C',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGLN78Q&Quantity.1=1',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HGLN78Q' url: 'https://www.amazon.de/dp/B08HGLN78Q',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HH1BMQQ' url: 'https://www.amazon.de/dp/B08HH1BMQQ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HJ9XFNM' url: 'https://www.amazon.de/dp/B08HJ9XFNM',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHLDS72&Quantity.1=1',
model: 'aorus master', model: 'aorus master',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08KHLDS72' url: 'https://www.amazon.de/dp/B08KHLDS72',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HHZVZ3N&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HHZVZ3N' url: 'https://www.amazon.de/dp/B08HHZVZ3N',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HLZXHZY&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HLZXHZY' url: 'https://www.amazon.de/dp/B08HLZXHZY',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KH7RL89&Quantity.1=1',
model: 'vision oc', model: 'vision oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08KH7RL89' url: 'https://www.amazon.de/dp/B08KH7RL89',
}, },
{ {
brand: 'inno3d', brand: 'inno3d',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JD6QPXD&Quantity.1=1',
model: 'twin x2 oc', model: 'twin x2 oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08JD6QPXD' url: 'https://www.amazon.de/dp/B08JD6QPXD',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HM4V2DH' url: 'https://www.amazon.de/dp/B08HM4V2DH',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HM4M621' url: 'https://www.amazon.de/dp/B08HM4M621',
}, },
{ {
brand: 'palit', brand: 'palit',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JCVWTQY&Quantity.1=1',
model: 'gaming pro', model: 'gaming pro',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08JCVWTQY' url: 'https://www.amazon.de/dp/B08JCVWTQY',
}, },
{ {
brand: 'palit', brand: 'palit',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JCKYYL8&Quantity.1=1',
model: 'gaming pro oc', model: 'gaming pro oc',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08JCKYYL8' url: 'https://www.amazon.de/dp/B08JCKYYL8',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HR1NPPQ&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.amazon.de/dp/B08HR1NPPQ' url: 'https://www.amazon.de/dp/B08HR1NPPQ',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix', cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN642LY&Quantity.1=1',
model: 'strix',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HN642LY' url: 'https://www.amazon.de/dp/B08HN642LY',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN51T8Q&Quantity.1=1',
model: 'strix oc',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HN51T8Q' url: 'https://www.amazon.de/dp/B08HN51T8Q',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN4FLFJ&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HN4FLFJ' url: 'https://www.amazon.de/dp/B08HN4FLFJ',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN5B8FJ&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HN5B8FJ' url: 'https://www.amazon.de/dp/B08HN5B8FJ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGFNPJQ&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HGFNPJQ' url: 'https://www.amazon.de/dp/B08HGFNPJQ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08J5NMDP7&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08J5NMDP7' url: 'https://www.amazon.de/dp/B08J5NMDP7',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGS1SXH&Quantity.1=1',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HGS1SXH' url: 'https://www.amazon.de/dp/B08HGS1SXH',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGZ4XSZ&Quantity.1=1',
model: 'xc3', model: 'xc3',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HGZ4XSZ' url: 'https://www.amazon.de/dp/B08HGZ4XSZ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGKQ527&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HGKQ527' url: 'https://www.amazon.de/dp/B08HGKQ527',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGTNDL4&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HGTNDL4' url: 'https://www.amazon.de/dp/B08HGTNDL4',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KH7R4FQ&Quantity.1=1',
model: 'aorus master', model: 'aorus master',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08KH7R4FQ' url: 'https://www.amazon.de/dp/B08KH7R4FQ',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HJPDJTY' url: 'https://www.amazon.de/dp/B08HJPDJTY',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHKDTSJ&Quantity.1=1',
model: 'turbo', model: 'turbo',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08KHKDTSJ' url: 'https://www.amazon.de/dp/B08KHKDTSJ',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HJRF2CN' url: 'https://www.amazon.de/dp/B08HJRF2CN',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HRBW6VB' url: 'https://www.amazon.de/dp/B08HRBW6VB',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM661YM&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HM661YM' url: 'https://www.amazon.de/dp/B08HM661YM',
}, },
{ {
brand: 'palit', brand: 'palit',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JQQ1VD1&Quantity.1=1',
model: 'gaming pro', model: 'gaming pro',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08JQQ1VD1' url: 'https://www.amazon.de/dp/B08JQQ1VD1',
}, },
{ {
brand: 'nvidia', brand: 'nvidia',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HR6ZBYJ&Quantity.1=1',
model: 'founders edition', model: 'founders edition',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HR6ZBYJ' url: 'https://www.amazon.de/dp/B08HR6ZBYJ',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3090', series: '3090',
url: 'https://www.amazon.de/dp/B08HJQ182D' url: 'https://www.amazon.de/dp/B08HJQ182D',
} },
{
brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HSJ1622&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.de/dp/B08HSJ1622',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHFZN9P&Quantity.1=1',
model: 'dual oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08KHFZN9P',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HT7PR9Y&Quantity.1=1',
model: 'strix',
series: '3070',
url: 'https://www.amazon.de/dp/B08HT7PR9Y',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
model: 'strix oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08L8JNTXQ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
model: 'ventus 2x oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08KWPDXJZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L6PCZTR&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08L6PCZTR',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming x trio',
series: '3070',
url: 'https://www.amazon.de/dp/B08KWN2LZG',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
model: 'vision oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08M13DXSZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHL21CV&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08KHL21CV',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHL2J5X&Quantity.1=1',
model: 'eagle oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08KHL2J5X',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3QCZKZ&Quantity.1=1',
model: 'xc3 black',
series: '3070',
url: 'https://www.amazon.de/dp/B08L3QCZKZ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3QZP7W&Quantity.1=1',
model: 'xc3',
series: '3070',
url: 'https://www.amazon.de/dp/B08L3QZP7W',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3Q41SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.de/dp/B08L3Q41SM',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HRBR7K9&Quantity.1=1',
model: 'twin edge',
series: '3070',
url: 'https://www.amazon.de/dp/B08HRBR7K9',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08LBVNKT1&Quantity.1=1',
model: 'twin edge oc',
series: '3070',
url: 'https://www.amazon.de/dp/B08LBVNKT1',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
model: 'dual fan',
series: '3070',
url: 'https://www.amazon.de/dp/B08HBF5L3K',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
model: 'xlr8 revel',
series: '3070',
url: 'https://www.amazon.de/dp/B08HBJB7YD',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.de/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.de/dp/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.de/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.de/dp/B0815Y8J9N',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H93ZRK9&Quantity.1=1',
labels: {
inStock: {
container: '#productTitle',
text: ['sony playstation 5'],
},
},
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.de/dp/B08H93ZRK9',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H98GVK8&Quantity.1=1',
labels: {
inStock: {
container: '#productTitle',
text: ['sony playstation 5'],
},
},
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.de/dp/B08H98GVK8',
},
{
brand: 'microsoft',
// Fixme: disabled because of #1095, enable when working again
// cartUrl:
// 'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H93ZRLL&Quantity.1=1',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.de/dp/B08H93ZRLL',
},
{
brand: 'microsoft',
// Fixme: disabled because of #1095, enable when working again
// cartUrl:
// 'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B087VM5XC6&Quantity.1=1',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.de/dp/B087VM5XC6',
},
], ],
name: 'amazon-de' name: 'amazon-de',
}; };
+121 -22
View File
@@ -1,105 +1,204 @@
import {Store} from './store'; import {Store} from './store';
export const AmazonEs: Store = { export const AmazonEs: Store = {
backoffStatusCodes: [403, 429, 503],
currency: '€',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['introduzca los caracteres que ve a continuación'] text: ['introduzca los caracteres que ve a continuación'],
}, },
inStock: { inStock: {
container: '#desktop_buybox', container: '#desktop_buybox',
text: ['añadir a la cesta'] text: ['añadir a la cesta'],
}, },
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]', container: '#priceblock_ourprice',
euroFormat: true },
} outOfStock: [
{
container: '#availability',
text: ['No disponible'],
},
],
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B07PW9VBK5&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.es/dp/B083JX52VG/' url: 'https://www.amazon.es/dp/B07PW9VBK5',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HM4V2DH' url: 'https://www.amazon.es/dp/B08HM4V2DH',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGYXP4C&Quantity.1=1',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HGYXP4C' url: 'https://www.amazon.es/dp/B08HGYXP4C',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HJ9XFNM' url: 'https://www.amazon.es/dp/B08HJ9XFNM',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGBYWQ6&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HGBYWQ6' url: 'https://www.amazon.es/dp/B08HGBYWQ6',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGLN78Q&Quantity.1=1',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HGLN78Q' url: 'https://www.amazon.es/dp/B08HGLN78Q',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HH1BMQQ' url: 'https://www.amazon.es/dp/B08HH1BMQQ',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HLZXHZY&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HLZXHZY' url: 'https://www.amazon.es/dp/B08HLZXHZY',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HHZVZ3N&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HHZVZ3N' url: 'https://www.amazon.es/dp/B08HHZVZ3N',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN37VQK&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HN37VQK' url: 'https://www.amazon.es/dp/B08HN37VQK',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN4DSTC&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HN4DSTC' url: 'https://www.amazon.es/dp/B08HN4DSTC',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix oc', cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN6KYS3&Quantity.1=1',
model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HN6KYS3' url: 'https://www.amazon.es/dp/B08HN6KYS3',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HM4M621' url: 'https://www.amazon.es/dp/B08HM4M621',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HR1NPPQ&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.amazon.es/dp/B08HR1NPPQ' url: 'https://www.amazon.es/dp/B08HR1NPPQ',
} },
{
brand: 'amd',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.es/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.es/dp/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.es/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.es/dp/B0815Y8J9N',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08KKJ37F7&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.es/dp/B08KKJ37F7',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08KJF2D25&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.es/dp/B08KJF2D25',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08H93ZRLL&Quantity.1=1',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.es/dp/B08H93ZRLL',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B087VM5XC6&Quantity.1=1',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.es/dp/B087VM5XC6',
},
], ],
name: 'amazon-es' name: 'amazon-es',
}; };
+191
View File
@@ -0,0 +1,191 @@
import {Store} from './store';
export const AmazonFr: Store = {
backoffStatusCodes: [403, 429, 503],
currency: '€',
labels: {
captcha: {
container: 'body',
text: ['entrez les caractères que vous voyez ci-dessous'],
},
inStock: {
container: '#desktop_buybox',
text: ['ajouter au panier'],
},
maxPrice: {
container: '#priceblock_ourprice',
euroFormat: true,
},
outOfStock: [
{
container: '#availability',
text: ['Actuellement indisponible'],
},
],
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amazon.fr/dp/B07PW9VBK5',
},
{
brand: 'msi',
model: 'gaming x trio',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR7SV3M',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR5SXPS',
},
{
brand: 'evga',
model: 'ftw3',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR3DPGW',
},
{
brand: 'evga',
model: 'ftw3 ultra',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR3Y5GQ',
},
{
brand: 'evga',
model: 'xc3 ultra',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR55YB5',
},
{
brand: 'evga',
model: 'xc3',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR4RJ3Q',
},
{
brand: 'evga',
model: 'xc3 black',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HR6FMF3',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HJTH61J',
},
{
brand: 'gigabyte',
model: 'eagle oc',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HJS2JLJ',
},
{
brand: 'asus',
model: 'tuf',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HHDP9DW',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HH5WF97',
},
{
brand: 'zotac',
model: 'trinity',
series: '3080',
url: 'https://www.amazon.fr/dp/B08HJNKT3P',
},
{
brand: 'zotac',
model: 'trinity',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HJQ182D',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HR9D2JS',
},
{
brand: 'gigabyte',
model: 'gaming oc',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HJRF2CN',
},
{
brand: 'gigabyte',
model: 'eagle oc',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HJPDJTY',
},
{
brand: 'asus',
model: 'tuf',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HJGNJ81',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3090',
url: 'https://www.amazon.fr/dp/B08HJLLF7G',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.fr/dp/B08166SLDF',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.fr/dp/B0815XFSGK',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.fr/dp/B08164VTWH',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.fr/dp/B0815Y8J9N',
},
{
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.fr/dp/B08H93ZRK9',
},
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.fr/dp/B08H98GVK8',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.fr/dp/B08H93ZRLL',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.fr/dp/B087VM5XC6',
},
],
name: 'amazon-fr',
};
+415
View File
@@ -0,0 +1,415 @@
import {Store} from './store';
export const AmazonIt: Store = {
backoffStatusCodes: [403, 429, 503],
currency: '€',
labels: {
captcha: {
container: 'body',
text: ['Inserisci i caratteri visualizzati nello spazio sottostante'],
},
inStock: {
container: '#desktop_buybox',
text: ['Aggiungi al carrello'],
},
maxPrice: {
container: '#priceblock_ourprice',
euroFormat: true,
},
},
links: [
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KHFZN9P&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.it/dp/B08KHFZN9P',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.it/dp/B08L8HPKR6',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
model: 'strix',
series: '3070',
url: 'https://www.amazon.it/dp/B08L8JNTXQ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
model: 'tuf',
series: '3070',
url: 'https://www.amazon.it/dp/B08L8KC1J7',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.it/dp/B08KY266MG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.it/dp/B08KWN2LZG',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
model: 'xlr8 revel',
series: '3070',
url: 'https://www.amazon.it/dp/B08HBJB7YD',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
model: 'xlr8 uprising',
series: '3070',
url: 'https://www.amazon.it/dp/B08HBF5L3K',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
model: 'ventus 2x oc',
series: '3070',
url: 'https://www.amazon.it/dp/B08KWPDXJZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.it/dp/B08KWLMZV4',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.it/dp/B08LF32LJ6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.it/dp/B08L8L71SM',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3070',
url: 'https://www.amazon.it/dp/B08L8L9TCZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.it/dp/B08KY266MG',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
model: 'vision oc',
series: '3070',
url: 'https://www.amazon.it/dp/B08M13DXSZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
model: 'eagle',
series: '3070',
url: 'https://www.amazon.it/dp/B08KXZV626',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.it/dp/B08HBR7QBM',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.it/dp/B08HBTJMLJ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3080',
url: 'https://www.amazon.it/dp/B08HR3Y5GQ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
model: 'xc3 ultra',
series: '3080',
url: 'https://www.amazon.it/dp/B08HR55YB5',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
model: 'xc3',
series: '3080',
url: 'https://www.amazon.it/dp/B08HR4RJ3Q',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
model: 'xc3 black',
series: '3080',
url: 'https://www.amazon.it/dp/B08HR6FMF3',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
model: 'gaming oc',
series: '3080',
url: 'https://www.amazon.it/dp/B08HJTH61J',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
model: 'eagle oc',
series: '3080',
url: 'https://www.amazon.it/dp/B08HJS2JLJ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
model: 'tuf oc',
series: '3080',
url: 'https://www.amazon.it/dp/B08HH5WF97',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
model: 'tuf',
series: '3080',
url: 'https://www.amazon.it/dp/B08HHDP9DW',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1',
model: 'strix oc',
series: '3090',
url: 'https://www.amazon.it/dp/B08J6GMWCQ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
model: 'ventus 3x oc',
series: '3080',
url: 'https://www.amazon.it/dp/B08HR5SXPS',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
model: 'trinity',
series: '3080',
url: 'https://www.amazon.it/dp/B08HJNKT3P',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
model: 'trinity',
series: '3090',
url: 'https://www.amazon.it/dp/B08HJQ182D',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1',
model: 'xlr8 revel',
series: '3090',
url: 'https://www.amazon.it/dp/B08HBQWBHH',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1',
model: 'xlr8 revel',
series: '3090',
url: 'https://www.amazon.it/dp/B08HBVX53D',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
model: 'gaming x trio',
series: '3090',
url: 'https://www.amazon.it/dp/B08HRBW6VB',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
model: 'ventus 3x',
series: '3090',
url: 'https://www.amazon.it/dp/B08HR9D2JS',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
model: 'gaming oc',
series: '3090',
url: 'https://www.amazon.it/dp/B08HJRF2CN',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
model: 'eagle oc',
series: '3090',
url: 'https://www.amazon.it/dp/B08HJPDJTY',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
model: 'tuf oc',
series: '3090',
url: 'https://www.amazon.it/dp/B08HJGNJ81',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
model: 'tuf oc',
series: '3090',
url: 'https://www.amazon.it/dp/B08HJLLF7G',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.it/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.it/dp/product/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.it/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.it/dp/B0815Y8J9N',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08MVC76SR&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.it/dp/B08MVC76SR',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08MVCLBWK&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.it/dp/B08MVCLBWK',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KKJ37F7&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.it/dp/B08KKJ37F7',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KJF2D25&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.it/dp/B08KJF2D25',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08JDSW1ZW&Quantity.1=1',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.it/dp/B08JDSW1ZW',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08JDTCXRG&Quantity.1=1',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.it/dp/B08JDTCXRG',
},
{
brand: 'corsair',
cartUrl:
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B07M63H81H&Quantity.1=1',
model: '750 platinum',
series: 'sf',
url: 'https://www.amazon.it/dp/B07M63H81H',
},
],
name: 'amazon-it',
};
+190 -19
View File
@@ -1,67 +1,238 @@
import {Store} from './store'; import {Store} from './store';
export const AmazonNl: Store = { export const AmazonNl: Store = {
currency: '€',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['voer de karakters in die u hieronder ziet'] text: ['voer de karakters in die u hieronder ziet'],
}, },
inStock: { inStock: [
container: '#availability', {
text: ['op voorraad', 'verkrijgbaar vanaf', 'wordt gewoonlijk verzonden binnen', 'nog slechts'] container: '#add-to-cart-button',
text: ['in winkelwagen'],
}, },
{
container: '#buy-now-button',
text: ['nu kopen'],
},
],
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]', container: '#priceblock_ourprice',
euroFormat: true euroFormat: true,
}, },
outOfStock: [ outOfStock: [
{ {
container: '#availability', container: '#availability',
text: ['tijdelijk niet'] text: ['tijdelijk niet'],
}, },
{ {
container: '#outOfStock', container: '#outOfStock',
text: ['we weten niet of en wanneer dit item weer op voorraad is'] text: ['we weten niet of en wanneer dit item weer op voorraad is'],
} },
] ],
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B085K45C3S&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.nl/dp/B083GGYNQ6' url: 'https://www.amazon.nl/dp/B085K45C3S',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.amazon.nl/dp/B08HM4M621' url: 'https://www.amazon.nl/dp/B08HM4M621',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3080',
url: 'https://www.amazon.nl/dp/B08HM4V2DH' url: 'https://www.amazon.nl/dp/B08HM4V2DH',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.nl/dp/B08HJ9XFNM' url: 'https://www.amazon.nl/dp/B08HJ9XFNM',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.amazon.nl/dp/B08HH1BMQQ' url: 'https://www.amazon.nl/dp/B08HH1BMQQ',
}, },
{ {
brand: 'asus', brand: 'asus',
model: 'rog strix', cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HN7VVLJ&Quantity.1=1',
model: 'strix',
series: '3080', series: '3080',
url: 'https://www.amazon.nl/dp/B08HN7VVLJ' url: 'https://www.amazon.nl/dp/B08HN7VVLJ',
} },
{
brand: 'msi',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
model: 'ventus 2x oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P2DQ28S',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW2YJB2&Quantity.1=1',
model: 'ventus 2x oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08NW2YJB2',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
model: 'twin edge',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P3XJLJJ',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P3V572B',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3BJ9Y8&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P3BJ9Y8',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3JPX8P&Quantity.1=1',
model: 'eagle',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P3JPX8P',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW2X37Z&Quantity.1=1',
model: 'gaming oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08NW2X37Z',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW528S1&Quantity.1=1',
model: 'eagle oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08NW528S1',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW693LG&Quantity.1=1',
model: 'xlr8 revel',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08NW693LG',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
model: 'tuf oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B083Z5P6TX',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NZ4G4T2&Quantity.1=1',
model: 'tuf oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08NZ4G4T2',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
model: 'dual oc',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08P2HBBLX',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDN36R3&Quantity.1=1',
model: 'ftw3',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08PDN36R3',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDP837W&Quantity.1=1',
model: 'xc gaming',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08PDP837W',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDMVPZ4&Quantity.1=1',
model: 'xc3 black',
series: '3060ti',
url: 'https://www.amazon.nl/dp/B08PDMVPZ4',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.nl/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.nl/dp/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.nl/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.nl/dp/B0815Y8J9N',
},
], ],
name: 'amazon-nl' name: 'amazon-nl',
}; };
+760
View File
@@ -0,0 +1,760 @@
import {Store} from './store';
export const AmazonSg: Store = {
backoffStatusCodes: [403, 429, 503],
currency: '$',
labels: {
captcha: {
container: 'body',
text: ['enter the characters you see below'],
},
inStock: [
{
container: '#add-to-cart-button',
text: ['add to cart'],
},
{
container: '#buy-now-button',
text: ['buy now'],
},
],
maxPrice: {
container: '#priceblock_ourprice',
},
},
links: [
{
brand: 'test:brand',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B083248S3B&Quantity.1=1',
model: 'test:model',
series: 'test:series',
url: 'https://www.amazon.sg/dp/B083248S3B',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
model: 'dual',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P2HBBLX',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NYP7KG6&Quantity.1=1',
model: 'gaming oc',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08NYP7KG6',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NYPLXPJ&Quantity.1=1',
model: 'gaming oc pro',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08NYPLXPJ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NYNJ6RC&Quantity.1=1',
model: 'eagle',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08NYNJ6RC',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
model: 'tuf',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B083Z5P6TX',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P2D3JSG&Quantity.1=1',
model: 'gaming x trio',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P2D3JSG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
model: 'ventus 2x',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P2DQ28S',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P3XJLJJ',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
model: 'twin edge',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P3V572B',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P2D1JZZ&Quantity.1=1',
model: 'ko',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P2D1JZZ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B083Z7TR8Z&Quantity.1=1',
model: 'strix',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B083Z7TR8Z',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P2H5LW2&Quantity.1=1',
model: 'ftw3',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08P2H5LW2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NYPKW1Z&Quantity.1=1',
model: 'eagle oc',
series: '3060ti',
url: 'https://www.amazon.sg/dp/B08NYPKW1Z',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8LG4M3&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8LG4M3',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8HPKR6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
model: 'xc3 black',
series: '3070',
url: 'https://www.amazon.sg/dp/B08LW46GH2',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
model: 'strix',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8JNTXQ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
model: 'tuf',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8KC1J7',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KY266MG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KWN2LZG',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
model: 'xlr8 revel',
series: '3070',
url: 'https://www.amazon.sg/dp/B08HBJB7YD',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
model: 'xlr8 uprising',
series: '3070',
url: 'https://www.amazon.sg/dp/B08HBF5L3K',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
model: 'ventus 2x oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KWPDXJZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KWLMZV4',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08LF1CWT2&Quantity.1=1',
model: 'twin edge oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08LF1CWT2',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.sg/dp/B08LF32LJ6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8L71SM',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3070',
url: 'https://www.amazon.sg/dp/B08L8L9TCZ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
model: 'xc3 black',
series: '3070',
url: 'https://www.amazon.sg/dp/B08LW46GH2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KY266MG',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
model: 'vision oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08M13DXSZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08M4YFNX2&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08M4YFNX2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
model: 'eagle',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KXZV626',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08KY322TH&Quantity.1=1',
model: 'eagle oc',
series: '3070',
url: 'https://www.amazon.sg/dp/B08KY322TH',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HBR7QBM',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HBTJMLJ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1',
model: 'gaming x trio',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR7SV3M',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR3Y5GQ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
model: 'xc3 ultra',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR55YB5',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1',
model: 'ftw3',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR3DPGW',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
model: 'xc3',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR4RJ3Q',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
model: 'xc3 black',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR6FMF3',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
model: 'gaming oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HJTH61J',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
model: 'eagle oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HJS2JLJ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
model: 'tuf oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HH5WF97',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
model: 'tuf',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HHDP9DW',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08J6F174Z&Quantity.1=1',
model: 'strix oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08J6F174Z',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1',
model: 'strix oc',
series: '3090',
url: 'https://www.amazon.sg/dp/B08J6GMWCQ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
model: 'ventus 3x oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HR5SXPS',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
model: 'trinity',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HJNKT3P',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HVV2P4Z&Quantity.1=1',
model: 'trinity oc',
series: '3080',
url: 'https://www.amazon.sg/dp/B08HVV2P4Z',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
model: 'trinity',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HJQ182D',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1',
model: 'xlr8 revel',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HBQWBHH',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1',
model: 'xlr8 revel',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HBVX53D',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
model: 'gaming x trio',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HRBW6VB',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
model: 'ventus 3x',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HR9D2JS',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08J5F3G18&Quantity.1=1',
model: 'ftw3 ultra',
series: '3090',
url: 'https://www.amazon.sg/dp/B08J5F3G18',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
model: 'gaming oc',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HJRF2CN',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
model: 'eagle oc',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HJPDJTY',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
model: 'tuf oc',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HJGNJ81',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
model: 'tuf oc',
series: '3090',
url: 'https://www.amazon.sg/dp/B08HJLLF7G',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.sg/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.sg/dp/product/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.sg/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.sg/dp/B0815Y8J9N',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08PHWJC8X&Quantity.1=1',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amazon.sg/dp/B08PHWJC8X',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08PDQJVD9&Quantity.1=1',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amazon.sg/dp/B08PDQJVD9',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NS4W2ZY&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NS4W2ZY',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08MVC76SR&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08MVC76SR',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NXXT7WN&Quantity.1=1',
model: 'nitro+',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NXXT7WN',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NXYNLMR&Quantity.1=1',
model: 'pulse',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NXYNLMR',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NXVNMPQ&Quantity.1=1',
model: 'nitro+',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NXVNMPQ',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08N6ZLX9B&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08N6ZLX9B',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NX14LV1&Quantity.1=1',
model: 'merc',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NX14LV1',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NN76VJD&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08NN76VJD',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P5YFZCY&Quantity.1=1',
model: 'merc',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08P5YFZCY',
},
{
brand: 'powercolor',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08MNZM5TK&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08MNZM5TK',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08MVCLBWK&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08MVCLBWK',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NXZSPMY&Quantity.1=1',
model: 'nitro+',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08NXZSPMY',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NXYBVDB&Quantity.1=1',
model: 'pulse',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08NXYBVDB',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NWJ29NB&Quantity.1=1',
model: 'strix oc',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08NWJ29NB',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08P3YT3MY&Quantity.1=1',
model: 'tuf oc',
series: 'rx6800',
url: 'https://www.amazon.sg/dp/B08P3YT3MY',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08NWHKGS9&Quantity.1=1',
model: 'strix lc',
series: 'rx6800xt',
url: 'https://www.amazon.sg/dp/B08NWHKGS9',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08FC5L3RG&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.sg/dp/B08FC5L3RG',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HNRSVQP&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.sg/dp/B08HNRSVQP',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08FC6MR62&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.sg/dp/B08FC6MR62',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B08HNSWWT7&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.sg/dp/B08HNSWWT7',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.sg/dp/B08H75RTZ8',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.sg/dp/B08G9J44ZN',
},
{
brand: 'corsair',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B07M63H81H&Quantity.1=1',
model: '750 platinum',
series: 'sf',
url: 'https://www.amazon.sg/dp/B07M63H81H',
},
{
brand: 'corsair',
cartUrl:
'https://www.amazon.sg/gp/aws/cart/add.html?ASIN.1=B07F84FJ1G&Quantity.1=1',
model: '600 platinum',
series: 'sf',
url: 'https://www.amazon.sg/dp/B07F84FJ1G',
},
],
name: 'amazon-sg',
};
+468 -63
View File
@@ -1,95 +1,500 @@
import {Link, Store} from './store'; import {Link, Store} from './store';
import {logger} from '../../logger';
import {parseCard} from './helpers/card';
export const AmazonUk: Store = { export const AmazonUk: Store = {
backoffStatusCodes: [403, 429, 503], backoffStatusCodes: [403, 429, 503],
currency: '£',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['enter the characters you see below'] text: ['enter the characters you see below'],
}, },
inStock: { inStock: {
container: '#availability', container: '#availability',
text: ['in stock'] text: ['in stock'],
}, },
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]' container: '#priceblock_ourprice',
}, },
outOfStock: [ outOfStock: [
{ {
container: '#availability', container: '#availability',
text: ['out of stock', 'unavailable'] text: ['out of stock', 'unavailable'],
}, },
{ {
container: '#backInStock', container: '#backInStock',
text: ['unavailable'] text: ['unavailable'],
} },
] ],
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl: 'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B081265T5Z&Quantity.1=1', cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B0753R2TWC&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.co.uk/dp/B081265T5Z/' url: 'https://www.amazon.co.uk/dp/B0753R2TWC/',
}
],
linksBuilder: {
builder: (docElement, series) => {
const productElements = docElement.find('.s-result-list .s-result-item[data-asin]');
const links: Link[] = [];
for (let i = 0; i < productElements.length; i++) {
const productElement = productElements.eq(i);
const asin = productElement.attr()['data-asin'];
if (!asin) {
continue;
}
const url = `https://www.amazon.co.uk/dp/${asin}/`;
const titleElement = productElement.find('.sg-col-inner h2 a.a-text-normal[href] span').first();
const title = titleElement.text().trim();
if (!title || !new RegExp(`RTX.*${series}`, 'i').exec(title)) {
continue;
}
const card = parseCard(title);
if (card) {
links.push({
brand: card.brand as any,
cartUrl: `https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=${asin}&Quantity.1=1`,
model: card.model,
series,
url
});
} else {
logger.error(`Failed to parse card: ${title}`);
}
}
return links;
}, },
ttl: 300000,
urls: [
{ {
brand: 'sony',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H95Y452&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.co.uk/dp/B08H95Y452',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H97NYGP&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.co.uk/dp/B08H97NYGP',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H93GKNJ&Quantity.1=1',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.co.uk/dp/B08H93GKNJ',
},
{
brand: 'microsoft',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08GD9MNZB&Quantity.1=1',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.co.uk/dp/B08GD9MNZB',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url:
'https://www.amazon.co.uk/AMD-Ryzen-5600X-Processor-Cache/dp/B08166SLDF',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url:
'https://www.amazon.co.uk/AMD-Ryzen-5800X-Processor-Cache/dp/B0815XFSGK',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url:
'https://www.amazon.co.uk/AMD-Ryzen-5900X-Processor-Cache/dp/B08164VTWH',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url:
'https://www.amazon.co.uk/AMD-Ryzen-5950X-Processor-Cache/dp/B0815Y8J9N',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HN7VVLJ&Quantity.1=1',
model: 'strix',
series: '3080', series: '3080',
url: [ url: 'https://www.amazon.co.uk/dp/B08HN7VVLJ',
'https://www.amazon.co.uk/s?k=%2B%22RTX+3080%22+-2080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675291',
'https://www.amazon.co.uk/s?k=%2B%22RTX+3080%22+-2080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675594&page=2'
]
}, },
{ {
series: '3090', brand: 'asus',
url: [ cartUrl:
'https://www.amazon.co.uk/s?k=%2B%22RTX+3090%22+-3080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675291', 'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HN6KYS3&Quantity.1=1',
'https://www.amazon.co.uk/s?k=%2B%22RTX+3090%22+-3080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675594&page=2' model: 'strix oc',
] series: '3080',
} url: 'https://www.amazon.co.uk/dp/B08HN6KYS3',
]
}, },
name: 'amazon-uk' {
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HN37VQK&Quantity.1=1',
model: 'tuf',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HN37VQK',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HN4DSTC&Quantity.1=1',
model: 'tuf oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HN4DSTC',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HGBYWQ6&Quantity.1=1',
model: 'ftw3',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HGBYWQ6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HGYXP4C&Quantity.1=1',
model: 'ftw3 ultra',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HGYXP4C',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HGLN78Q&Quantity.1=1',
model: 'xc3',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HGLN78Q',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
model: 'xc3 black',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HH1BMQQ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
model: 'xc3 ultra',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HJ9XFNM',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KHLDS72&Quantity.1=1',
model: 'aorus master',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08KHLDS72',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HHZVZ3N&Quantity.1=1',
model: 'eagle oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HHZVZ3N',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HLZXHZY&Quantity.1=1',
model: 'gaming oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HLZXHZY',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KH7RL89&Quantity.1=1',
model: 'vision oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08KH7RL89',
},
{
brand: 'inno3d',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08JD6QPXD&Quantity.1=1',
model: 'twin x2 oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08JD6QPXD',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
model: 'gaming x trio',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HM4V2DH',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
model: 'ventus 3x oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HM4M621',
},
{
brand: 'palit',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08JCVWTQY&Quantity.1=1',
model: 'gaming pro',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08JCVWTQY',
},
{
brand: 'palit',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08JCKYYL8&Quantity.1=1',
model: 'gaming pro oc',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08JCKYYL8',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HR1NPPQ&Quantity.1=1',
model: 'trinity',
series: '3080',
url: 'https://www.amazon.co.uk/dp/B08HR1NPPQ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KHFZN9P&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KHFZN9P',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08L8HPKR6',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
model: 'strix',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08L8JNTXQ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
model: 'tuf',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08L8KC1J7',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KY266MG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KWN2LZG',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
model: 'xlr8 revel',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08HBJB7YD',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
model: 'xlr8 uprising',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08HBF5L3K',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
model: 'ventus 2x oc',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KWPDXJZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KWLMZV4',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08LF32LJ6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08L8L71SM',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08L8L9TCZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KY266MG',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
model: 'vision oc',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08M13DXSZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
model: 'eagle',
series: '3070',
url: 'https://www.amazon.co.uk/dp/B08KXZV626',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
model: 'ventus 2x oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P2DQ28S',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08NW2YJB2&Quantity.1=1',
model: 'ventus 2x oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08NW2YJB2',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
model: 'twin edge',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P3XJLJJ',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P3V572B',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P3BJ9Y8&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P3BJ9Y8',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P3JPX8P&Quantity.1=1',
model: 'eagle',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P3JPX8P',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08NW2X37Z&Quantity.1=1',
model: 'gaming oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08NW2X37Z',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08NW528S1&Quantity.1=1',
model: 'eagle oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08NW528S1',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08NW693LG&Quantity.1=1',
model: 'xlr8 revel',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08NW693LG',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
model: 'tuf oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B083Z5P6TX',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08NZ4G4T2&Quantity.1=1',
model: 'tuf oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08NZ4G4T2',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
model: 'dual oc',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08P2HBBLX',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08PDN36R3&Quantity.1=1',
model: 'ftw3',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08PDN36R3',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08PDP837W&Quantity.1=1',
model: 'xc gaming',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08PDP837W',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08PDMVPZ4&Quantity.1=1',
model: 'xc3 black',
series: '3060ti',
url: 'https://www.amazon.co.uk/dp/B08PDMVPZ4',
},
],
name: 'amazon-uk',
}; };
+622 -71
View File
@@ -1,202 +1,753 @@
import {Store} from './store'; import {Store} from './store';
export const Amazon: Store = { export const Amazon: Store = {
backoffStatusCodes: [403, 429, 503],
captchaDeterrent: {
hardLinks: [
'https://www.amazon.com/Amazon-Video/b/?ie=UTF8&node=2858778011&ref_=nav_cs_prime_video',
'https://www.amazon.com/alm/storefront?almBrandId=VUZHIFdob2xlIEZvb2Rz&ref_=nav_cs_whole_foods_in_region',
'https://www.amazon.com/gp/goldbox?ref_=nav_cs_gb',
],
searchTerms: ['goober', 'dungeons+and+dragons'],
searchUrl: 'https://www.amazon.com/s?k=%%s&i=todays-deals&ref=nb_sb_noss_2',
},
currency: '$',
labels: { labels: {
captcha: { captcha: {
container: 'body', container: 'body',
text: ['enter the characters you see below'] text: ['enter the characters you see below'],
}, },
inStock: { inStock: [
container: '#desktop_buybox', {
text: ['add to cart'] container: '#add-to-cart-button',
text: ['add to cart'],
}, },
{
container: '#buy-now-button',
text: ['buy now'],
},
],
maxPrice: { maxPrice: {
container: 'span[class*="PriceString"]' container: '#priceblock_ourprice',
} },
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B07TDN1SC5&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B089KV4YYX&Quantity.1=1',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.amazon.com/dp/B07TDN1SC5' url: 'https://www.amazon.com/dp/B089KV4YYX',
}, },
{ {
brand: 'pny', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1', cartUrl:
model: 'xlr8', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
series: '3080', model: 'dual',
url: 'https://www.amazon.com/dp/B08HBR7QBM' series: '3060ti',
url: 'https://www.amazon.com/dp/B08P2HBBLX',
}, },
{ {
brand: 'pny', brand: 'gigabyte',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1', cartUrl:
model: 'xlr8 rgb', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYP7KG6&Quantity.1=1',
series: '3080', model: 'gaming oc',
url: 'https://www.amazon.com/dp/B08HBTJMLJ' series: '3060ti',
url: 'https://www.amazon.com/dp/B08NYP7KG6',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYPLXPJ&Quantity.1=1',
model: 'gaming oc pro',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08NYPLXPJ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYNJ6RC&Quantity.1=1',
model: 'eagle',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08NYNJ6RC',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
model: 'tuf',
series: '3060ti',
url: 'https://www.amazon.com/dp/B083Z5P6TX',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2D3JSG&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3080', series: '3060ti',
url: 'https://www.amazon.com/dp/B08HR7SV3M' url: 'https://www.amazon.com/dp/B08P2D3JSG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
model: 'ventus 2x',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08P2DQ28S',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
model: 'twin edge oc',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08P3XJLJJ',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
model: 'twin edge',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08P3V572B',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2D1JZZ&Quantity.1=1',
model: 'ko',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08P2D1JZZ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B083Z7TR8Z&Quantity.1=1',
model: 'strix',
series: '3060ti',
url: 'https://www.amazon.com/dp/B083Z7TR8Z',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2H5LW2&Quantity.1=1',
model: 'ftw3',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08P2H5LW2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYPKW1Z&Quantity.1=1',
model: 'eagle oc',
series: '3060ti',
url: 'https://www.amazon.com/dp/B08NYPKW1Z',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8LG4M3&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8LG4M3',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
model: 'dual',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8HPKR6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
model: 'xc3 black',
series: '3070',
url: 'https://www.amazon.com/dp/B08LW46GH2',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
model: 'strix',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8JNTXQ',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
model: 'tuf',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8KC1J7',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08KY266MG',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.com/dp/B08KWN2LZG',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
model: 'xlr8 revel',
series: '3070',
url: 'https://www.amazon.com/dp/B08HBJB7YD',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
model: 'xlr8 uprising',
series: '3070',
url: 'https://www.amazon.com/dp/B08HBF5L3K',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
model: 'ventus 2x oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08KWPDXJZ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
model: 'ventus 3x oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08KWLMZV4',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LF1CWT2&Quantity.1=1',
model: 'twin edge oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08LF1CWT2',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
model: 'gaming',
series: '3070',
url: 'https://www.amazon.com/dp/B08LF32LJ6',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
model: 'xc3 ultra',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8L71SM',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
model: 'ftw3 ultra',
series: '3070',
url: 'https://www.amazon.com/dp/B08L8L9TCZ',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
model: 'xc3 black',
series: '3070',
url: 'https://www.amazon.com/dp/B08LW46GH2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08KY266MG',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
model: 'vision oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08M13DXSZ',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08M4YFNX2&Quantity.1=1',
model: 'gaming oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08M4YFNX2',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
model: 'eagle',
series: '3070',
url: 'https://www.amazon.com/dp/B08KXZV626',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY322TH&Quantity.1=1',
model: 'eagle oc',
series: '3070',
url: 'https://www.amazon.com/dp/B08KY322TH',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.com/dp/B08HBR7QBM',
},
{
brand: 'pny',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1',
model: 'xlr8 revel',
series: '3080',
url: 'https://www.amazon.com/dp/B08HBTJMLJ',
},
{
brand: 'msi',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1',
model: 'gaming x trio',
series: '3080',
url: 'https://www.amazon.com/dp/B08HR7SV3M',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
model: 'ftw3 ultra', model: 'ftw3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR3Y5GQ' url: 'https://www.amazon.com/dp/B08HR3Y5GQ',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
model: 'xc3 ultra', model: 'xc3 ultra',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR55YB5' url: 'https://www.amazon.com/dp/B08HR55YB5',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1',
model: 'ftw3', model: 'ftw3',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR3DPGW' url: 'https://www.amazon.com/dp/B08HR3DPGW',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
model: 'xc3', model: 'xc3',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR4RJ3Q' url: 'https://www.amazon.com/dp/B08HR4RJ3Q',
}, },
{ {
brand: 'evga', brand: 'evga',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
model: 'xc3 black', model: 'xc3 black',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR6FMF3' url: 'https://www.amazon.com/dp/B08HR6FMF3',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HJTH61J' url: 'https://www.amazon.com/dp/B08HJTH61J',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HJS2JLJ' url: 'https://www.amazon.com/dp/B08HJS2JLJ',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HH5WF97' url: 'https://www.amazon.com/dp/B08HH5WF97',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
model: 'tuf', model: 'tuf',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HHDP9DW' url: 'https://www.amazon.com/dp/B08HHDP9DW',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6F174Z&Quantity.1=1', cartUrl:
model: 'rog strix oc', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6F174Z&Quantity.1=1',
model: 'strix oc',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08J6F174Z' url: 'https://www.amazon.com/dp/B08J6F174Z',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1', cartUrl:
model: 'rog strix oc', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1',
model: 'strix oc',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08J6GMWCQ' url: 'https://www.amazon.com/dp/B08J6GMWCQ',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
model: 'ventus 3x oc', model: 'ventus 3x oc',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HR5SXPS' url: 'https://www.amazon.com/dp/B08HR5SXPS',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3080', series: '3080',
url: 'https://www.amazon.com/dp/B08HJNKT3P' url: 'https://www.amazon.com/dp/B08HJNKT3P',
}, },
{ {
brand: 'zotac', brand: 'zotac',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HVV2P4Z&Quantity.1=1',
model: 'trinity oc',
series: '3080',
url: 'https://www.amazon.com/dp/B08HVV2P4Z',
},
{
brand: 'zotac',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
model: 'trinity', model: 'trinity',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HJQ182D' url: 'https://www.amazon.com/dp/B08HJQ182D',
}, },
{ {
brand: 'pny', brand: 'pny',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1', cartUrl:
model: 'xlr8', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1',
model: 'xlr8 revel',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HBQWBHH' url: 'https://www.amazon.com/dp/B08HBQWBHH',
}, },
{ {
brand: 'pny', brand: 'pny',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1', cartUrl:
model: 'xlr8', 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1',
model: 'xlr8 revel',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HBVX53D' url: 'https://www.amazon.com/dp/B08HBVX53D',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
model: 'gaming x trio', model: 'gaming x trio',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HRBW6VB' url: 'https://www.amazon.com/dp/B08HRBW6VB',
}, },
{ {
brand: 'msi', brand: 'msi',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
model: 'ventus 3x', model: 'ventus 3x',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HR9D2JS' url: 'https://www.amazon.com/dp/B08HR9D2JS',
},
{
brand: 'evga',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J5F3G18&Quantity.1=1',
model: 'ftw3 ultra',
series: '3090',
url: 'https://www.amazon.com/dp/B08J5F3G18',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
model: 'gaming oc', model: 'gaming oc',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HJRF2CN' url: 'https://www.amazon.com/dp/B08HJRF2CN',
}, },
{ {
brand: 'gigabyte', brand: 'gigabyte',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
model: 'eagle oc', model: 'eagle oc',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HJPDJTY' url: 'https://www.amazon.com/dp/B08HJPDJTY',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HJGNJ81' url: 'https://www.amazon.com/dp/B08HJGNJ81',
}, },
{ {
brand: 'asus', brand: 'asus',
cartUrl: 'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1', cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
model: 'tuf oc', model: 'tuf oc',
series: '3090', series: '3090',
url: 'https://www.amazon.com/dp/B08HJLLF7G' url: 'https://www.amazon.com/dp/B08HJLLF7G',
} },
{
brand: 'amd',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amazon.com/dp/B08166SLDF',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amazon.com/dp/product/B0815XFSGK',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amazon.com/dp/B08164VTWH',
},
{
brand: 'amd',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amazon.com/dp/B0815Y8J9N',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08PHWJC8X&Quantity.1=1',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amazon.com/dp/B08PHWJC8X',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08PDQJVD9&Quantity.1=1',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amazon.com/dp/B08PDQJVD9',
},
{
brand: 'gigabyte',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NS4W2ZY&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NS4W2ZY',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MVC76SR&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08MVC76SR',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXXT7WN&Quantity.1=1',
model: 'nitro+',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NXXT7WN',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXYNLMR&Quantity.1=1',
model: 'pulse',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NXYNLMR',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXVNMPQ&Quantity.1=1',
model: 'nitro+',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NXVNMPQ',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08N6ZLX9B&Quantity.1=1',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08N6ZLX9B',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NX14LV1&Quantity.1=1',
model: 'merc',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NX14LV1',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NN76VJD&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08NN76VJD',
},
{
brand: 'xfx',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P5YFZCY&Quantity.1=1',
model: 'merc',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08P5YFZCY',
},
{
brand: 'powercolor',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MNZM5TK&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08MNZM5TK',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MVCLBWK&Quantity.1=1',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08MVCLBWK',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXZSPMY&Quantity.1=1',
model: 'nitro+',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08NXZSPMY',
},
{
brand: 'sapphire',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXYBVDB&Quantity.1=1',
model: 'pulse',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08NXYBVDB',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NWJ29NB&Quantity.1=1',
model: 'strix oc',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08NWJ29NB',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3YT3MY&Quantity.1=1',
model: 'tuf oc',
series: 'rx6800',
url: 'https://www.amazon.com/dp/B08P3YT3MY',
},
{
brand: 'asus',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NWHKGS9&Quantity.1=1',
model: 'strix lc',
series: 'rx6800xt',
url: 'https://www.amazon.com/dp/B08NWHKGS9',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08FC5L3RG&Quantity.1=1',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.amazon.com/dp/B08FC5L3RG',
},
{
brand: 'sony',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08FC6MR62&Quantity.1=1',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.amazon.com/dp/B08FC6MR62',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.amazon.com/dp/B08H75RTZ8',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.amazon.com/dp/B08G9J44ZN',
},
{
brand: 'corsair',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B07M63H81H&Quantity.1=1',
model: '750 platinum',
series: 'sf',
url: 'https://www.amazon.com/dp/B07M63H81H',
},
{
brand: 'corsair',
cartUrl:
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B07F84FJ1G&Quantity.1=1',
model: '600 platinum',
series: 'sf',
url: 'https://www.amazon.com/dp/B07F84FJ1G',
},
], ],
name: 'amazon' name: 'amazon',
}; };
+48
View File
@@ -0,0 +1,48 @@
import {Store} from './store';
export const AmdCa: Store = {
currency: '$',
labels: {
inStock: {
container: '.btn-shopping-cart',
text: ['add to cart'],
},
maxPrice: {
container: '.product-page-description h4',
euroFormat: false,
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amd.com/en/direct-buy/5458373400/ca',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458373400/ca?add-to-cart=true',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amd.com/en/direct-buy/5458373400/ca',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458372800/ca?add-to-cart=true',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amd.com/en/direct-buy/5458372800/ca',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458372200/ca?add-to-cart=true',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amd.com/en/direct-buy/5458372200/ca',
},
],
name: 'amd-ca',
};
+84
View File
@@ -0,0 +1,84 @@
import {Store} from './store';
export const AmdDe: Store = {
currency: '€',
labels: {
inStock: {
container: '.btn-shopping-cart',
text: ['add to cart'],
},
maxPrice: {
container: '.product-page-description h4',
euroFormat: true,
},
outOfStock: {
container: '.btn-radeon',
text: ['ausverkauft'],
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amd.com/de/direct-buy/5450881400/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5450881400/de?add-to-cart=true',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amd.com/de/direct-buy/5450881400/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5450881500/de?add-to-cart=true',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amd.com/de/direct-buy/5450881500/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5450881600/de?add-to-cart=true',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amd.com/de/direct-buy/5450881600/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5450881700/de?add-to-cart=true',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amd.com/de/direct-buy/5450881700/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5458374000/de?add-to-cart=true',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amd.com/de/direct-buy/5458374000/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5458374100/de?add-to-cart=true',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amd.com/de/direct-buy/5458374100/de',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/de/direct-buy/5458374200/de?add-to-cart=true',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amd.com/de/direct-buy/5458374200/de',
},
],
name: 'amd-de',
};
+64
View File
@@ -0,0 +1,64 @@
import {Store} from './store';
export const AmdIt: Store = {
currency: '€',
labels: {
inStock: {
container: '.btn-shopping-cart',
text: ['add to cart'],
},
maxPrice: {
container: '.product-page-description h4',
euroFormat: true,
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amd.com/en/direct-buy/5450881400/it',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881400/it?add-to-cart=true',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amd.com/en/direct-buy/5450881400/it',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881500/it?add-to-cart=true',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amd.com/en/direct-buy/5450881500/it',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881600/it?add-to-cart=true',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amd.com/en/direct-buy/5450881600/it',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881700/it?add-to-cart=true',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amd.com/en/direct-buy/5450881700/it',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458374100/it?add-to-cart=true',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amd.com/en/direct-buy/5458374100/it',
},
],
name: 'amd-it',
};
+96
View File
@@ -0,0 +1,96 @@
import {Store} from './store';
export const AmdUk: Store = {
currency: '£',
labels: {
inStock: [
{
container: '.btn-shopping-cart',
text: ['add to cart'],
},
{
container: '.btn-radeon',
text: ['add to cart'],
},
],
maxPrice: {
container: '.product-page-description h4',
euroFormat: false,
},
outOfStock: [
{
container: '.product-out-of-stock',
text: ['out of stock'],
},
{
container: '.btn-radeon',
text: ['sold out'],
},
],
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amd.com/en/direct-buy/5450881400/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881400/gb?add-to-cart=true',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amd.com/en/direct-buy/5450881400/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881500/gb?add-to-cart=true',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amd.com/en/direct-buy/5450881500/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881600/gb?add-to-cart=true',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amd.com/en/direct-buy/5450881600/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881700/gb?add-to-cart=true',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amd.com/en/direct-buy/5450881700/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458374000/gb?add-to-cart=true',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amd.com/en/direct-buy/5458374000/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458374100/gb?add-to-cart=true',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amd.com/en/direct-buy/5458374100/gb',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458374200/gb?add-to-cart=true',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amd.com/en/direct-buy/5458374200/gb',
},
],
name: 'amd-uk',
};
+80
View File
@@ -0,0 +1,80 @@
import {Store} from './store';
export const Amd: Store = {
currency: '$',
labels: {
inStock: {
container: '.btn-shopping-cart',
text: ['add to cart'],
},
maxPrice: {
container: '.product-page-description h4',
euroFormat: false,
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.amd.com/en/direct-buy/5450881400/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881400/us?add-to-cart=true',
model: '5950x',
series: 'ryzen5950',
url: 'https://www.amd.com/en/direct-buy/5450881400/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881500/us?add-to-cart=true',
model: '5900x',
series: 'ryzen5900',
url: 'https://www.amd.com/en/direct-buy/5450881500/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881600/us?add-to-cart=true',
model: '5800x',
series: 'ryzen5800',
url: 'https://www.amd.com/en/direct-buy/5450881600/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5450881700/us?add-to-cart=true',
model: '5600x',
series: 'ryzen5600',
url: 'https://www.amd.com/en/direct-buy/5450881700/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458372200/us?add-to-cart=true',
model: 'amd reference',
series: 'rx6900xt',
url: 'https://www.amd.com/en/direct-buy/5458372200/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458372800/us?add-to-cart=true',
model: 'amd reference',
series: 'rx6800xt',
url: 'https://www.amd.com/en/direct-buy/5458372800/us',
},
{
brand: 'amd',
cartUrl:
'https://www.amd.com/en/direct-buy/5458373400/us?add-to-cart=true',
model: 'amd reference',
series: 'rx6800',
url: 'https://www.amd.com/en/direct-buy/5458373400/us',
},
],
name: 'amd',
};
+43
View File
@@ -0,0 +1,43 @@
import {Store} from './store';
export const AntOnline: Store = {
currency: '$',
labels: {
inStock: {
container: '.uk-button',
text: ['Add to Cart'],
},
maxPrice: {
container: '.cPrice',
euroFormat: false,
},
outOfStock: {
container: '.priceView-price .priceView-hero-price span',
text: ['Sold Out'],
},
},
links: [
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url:
'https://www.antonline.com/Sony/Electronics/Gaming_Devices/Gaming_Consoles/1409507',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url:
'https://www.antonline.com/Microsoft/Electronics/Gaming_Devices/Gaming_Consoles/1414487',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url:
'https://www.antonline.com/Microsoft/Electronics/Gaming_Devices/Gaming_Consoles/1409527',
},
],
name: 'antonline',
};
+35
View File
@@ -0,0 +1,35 @@
import {Store} from './store';
export const ArgosIE: Store = {
currency: '€',
labels: {
inStock: {
container: '.btnbuyreserve',
text: ['buy or reserve'],
},
maxPrice: {
container: '.price',
},
outOfStock: {
container: '#subCopy',
text: ["We're working hard to get more stock."],
},
},
links: [
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url:
'http://www.argos.ie/static/Product/partNumber/8448262/Trail/searchtext%3EXBOX+SERIES+X.htm',
},
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url:
'http://www.argos.ie/static/Product/partNumber/8349000/Trail/searchtext%3EPS5+CONSOLE.htm',
},
],
name: 'argos-ie',
};
+47
View File
@@ -0,0 +1,47 @@
import {Store} from './store';
export const Argos: Store = {
currency: '£',
labels: {
inStock: {
container: 'button[data-test="add-to-trolley-button-button"',
text: ['to trolley'],
},
maxPrice: {
container: 'li[itemprop="price"]',
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url: 'https://www.argos.co.uk/product/5718469',
},
{
brand: 'sony',
model: 'ps5 console',
series: 'sonyps5c',
url: 'https://www.argos.co.uk/product/8349000',
},
{
brand: 'sony',
model: 'ps5 digital',
series: 'sonyps5de',
url: 'https://www.argos.co.uk/product/8349024',
},
{
brand: 'microsoft',
model: 'xbox series x',
series: 'xboxsx',
url: 'https://www.argos.co.uk/product/8448262',
},
{
brand: 'microsoft',
model: 'xbox series s',
series: 'xboxss',
url: 'https://www.argos.co.uk/product/8448248',
},
],
name: 'argos',
};
+33 -12
View File
@@ -2,45 +2,66 @@ import {Store} from './store';
import {getProductLinksBuilder} from './helpers/card'; import {getProductLinksBuilder} from './helpers/card';
export const Aria: Store = { export const Aria: Store = {
currency: '£',
labels: { labels: {
inStock: { inStock: {
container: '#addQuantity', container: '#addQuantity',
text: ['add to shopping basket'] text: ['add to shopping basket'],
}, },
maxPrice: { maxPrice: {
container: '.priceBig', container: '.priceBig',
euroFormat: false // Note: Aria uses non-euroFromat as price seperator euroFormat: false, // Note: Aria uses non-euroFromat as price seperator
}, },
outOfStock: { outOfStock: {
container: '.fBox', container: '.fBox',
text: ['out of stock', 'there is currently no stock of this item'] text: ['out of stock', 'there is currently no stock of this item'],
} },
}, },
links: [ links: [
{ {
brand: 'test:brand', brand: 'test:brand',
model: 'test:model', model: 'test:model',
series: 'test:series', series: 'test:series',
url: 'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+2060+Super/Gigabyte+NVIDIA+GeForce+RTX+2060+SUPER+8GB+WINDFORCE+OC+Turing+Graphics+Card+%2B+RTX+Bundle%21?productId=71541' url:
} 'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+2060+Super/Gigabyte+NVIDIA+GeForce+RTX+2060+SUPER+8GB+WINDFORCE+OC+Turing+Graphics+Card+%2B+RTX+Bundle%21?productId=71541',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url:
'https://www.aria.co.uk/Products/Components/Processors/AMD+CPUs/Ryzen+9+-+Socket+AM4/AMD+Ryzen+9+5950X+16+Core+AM4+CPU%2FProcessor?productId=72868',
},
], ],
linksBuilder: { linksBuilder: {
builder: getProductLinksBuilder({ builder: getProductLinksBuilder({
productsSelector: '#productListingInner .listTable .listTableTr', productsSelector: '#productListingInner .listTable .listTableTr',
sitePrefix: 'https://www.aria.co.uk', sitePrefix: 'https://www.aria.co.uk',
titleSelector: 'strong > a[href]' titleSelector: 'strong > a[href]',
}), }),
urls: [ urls: [
{
series: '3060ti',
url:
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3060+Ti',
},
{
series: '3070',
url:
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3070',
},
{ {
series: '3080', series: '3080',
url: 'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3080' url:
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3080',
}, },
{ {
series: '3090', series: '3090',
url: 'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3090' url:
} 'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3090',
] },
],
}, },
name: 'aria', name: 'aria',
waitUntil: 'domcontentloaded' waitUntil: 'domcontentloaded',
}; };
+141
View File
@@ -0,0 +1,141 @@
import {Store} from './store';
export const Arlt: Store = {
currency: '€',
labels: {
inStock: {
container: '.articleDesc .shippingtext',
text: ['auf Lager', 'Lieferzeit 2-3 Werktage', 'Ware im Zulauf'],
},
maxPrice: {
container: '.articleprice .price',
euroFormat: true,
},
outOfStock: {
container: '.articleDesc .shippingtext',
text: ['Neuer Artikel in Kürze verfügbar', 'Liefertermin unbekannt'],
},
},
links: [
{
brand: 'test:brand',
model: 'test:model',
series: 'test:series',
url:
'https://www.arlt.com/ASUS-GeForce-GTX1650-Super-TUF-GTX1650S-O4G-GAMING.html',
},
{
brand: 'asus',
model: 'dual',
series: '3070',
url:
'https://www.arlt.com/Gaming/Gaming-Hardware/Grafikkarten/ASUS-Dual-GeForce-RTX-3070.html',
},
{
brand: 'asus',
model: 'dual oc',
series: '3070',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/ASUS-Dual-GeForce-RTX-3070-OC.html',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3070',
url:
'https://www.arlt.com/Gaming/Gaming-Hardware/Grafikkarten/ASUS-TUF-Gaming-GeForce-RTX-3070-OC.html',
},
{
brand: 'asus',
model: 'strix',
series: '3070',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3070/ASUS-ROG-Strix-GeForce-RTX-3070.html',
},
{
brand: 'msi',
model: 'ventus 2x oc',
series: '3070',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3070/MSI-GeForce-RTX-3070-Ventus-2X-OC.html',
},
{
brand: 'gainward',
model: 'phoenix',
series: '3070',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/Gainward-GeForce-RTX-3070-Phoenix.html',
},
{
brand: 'gainward',
model: 'phoenix gs',
series: '3070',
url:
'https://www.arlt.com/Gaming/Gaming-Hardware/Gainward-GeForce-RTX-3070-Phoenix-GS.html',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3080',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/ASUS-TUF-Gaming-GeForce-RTX-3080-OC.html',
},
{
brand: 'msi',
model: 'ventus 3x oc',
series: '3080',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3080/MSI-GeForce-RTX-3080-Ventus-3X-OC.html',
},
{
brand: 'asus',
model: 'tuf oc',
series: '3090',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3090/ASUS-TUF-Gaming-GeForce-RTX-3090-OC.html',
},
{
brand: 'asus',
model: 'strix oc',
series: '3090',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3090/ASUS-ROG-Strix-GeForce-RTX-3090-OC.html',
},
{
brand: 'gainward',
model: 'phoenix gs',
series: '3090',
url:
'https://www.arlt.com/Gaming/Gaming-Hardware/Gainward-GeForce-RTX-3090-Phoenix-GS.html',
},
{
brand: 'amd',
model: '5600x',
series: 'ryzen5600',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-5-5600X-boxed.html',
},
{
brand: 'amd',
model: '5800x',
series: 'ryzen5800',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-7-5800X-boxed.html',
},
{
brand: 'amd',
model: '5900x',
series: 'ryzen5900',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-9-5900X-boxed.html',
},
{
brand: 'amd',
model: '5950x',
series: 'ryzen5950',
url:
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-9-5950X-boxed.html',
},
],
name: 'arlt',
};

Some files were not shown because too many files have changed in this diff Show More