Archived
1
0
Fork 0
This repository has been archived on 2024-12-18. You can view files and clone it, but cannot push or open issues or pull requests.
restockbot/README.md

169 lines
5.3 KiB
Markdown
Raw Normal View History

# RestockBot
2020-12-27 18:27:07 +01:00
Year 2020 has been quite hard for hardware supply. Graphics cards are out of stock everywhere. Nobody can grab the new generation (AMD RX 6000 series, NVIDIA GeForce RTX 3000 series). Even older generations are hard to find. `RestockBot` is a bot that crawl retailers websites and notify when a product is available.
2020-12-27 18:27:07 +01:00
## Requirements
### Headless browser
Use Docker:
2020-12-27 18:27:07 +01:00
```
docker run --name chromium --rm -d -p 9222:9222 montferret/chromium
2020-12-27 18:27:07 +01:00
```
Or get inspired by the [source code](https://github.com/MontFerret/chromium) to run it on your own.
2020-12-27 18:27:07 +01:00
### Twitter (optional)
2020-12-27 18:27:07 +01:00
Follow [this procedure](https://github.com/jouir/twitter-login) to generate all the required settings:
* `consumer_key`
* `consumer_secret`
* `access_token`
* `access_token_secret`
2020-12-27 18:27:07 +01:00
## Installation
2020-12-27 18:27:07 +01:00
Download the latest [release](https://github.com/jouir/restockbot/releases).
2020-12-27 18:27:07 +01:00
Ensure checksums are identical.
2020-12-27 18:27:07 +01:00
Then execute the binary:
2020-12-27 18:27:07 +01:00
```
./restockbot -version
./restockbot -help
2020-12-27 18:27:07 +01:00
```
## Compilation
2020-12-27 18:27:07 +01:00
Clone the repository:
2020-12-27 18:27:07 +01:00
```
git clone https://github.com/jouir/restockbot.git
2020-12-27 18:27:07 +01:00
```
Build the `restockbot` binary:
2020-12-27 18:27:07 +01:00
```
make build
ls -l bin/restockbot
2020-12-27 18:27:07 +01:00
```
Build with the architecture in the binary name:
2020-12-27 18:27:07 +01:00
```
make release
2020-12-27 18:27:07 +01:00
```
Eventually remove produced binaries with:
2020-12-27 18:27:07 +01:00
```
make clean
2020-12-27 18:27:07 +01:00
```
## Configuration
Default file is `restockbot.json` in the current directory. The file name can be passed with the `-config` argument.
2020-12-27 18:27:07 +01:00
Options:
* `urls`: list of retailers web pages
* `twitter` (optional):
* `consumer_key`: API key of your Twitter application
* `consumer_secret`: API secret of your Twitter application
* `access_token`: authentication token generated for your Twitter account
* `access_token_secret`: authentication token secret generated for your Twitter account
* `hashtags`: list of key/value used to append hashtags to each tweet. Key is the pattern to match in the product name, value is the string to append to the tweet. For example, `{"twitter": {"hashtags": [{"rtx 3090": "#nvidia #rtx3090"}]}}` will detect `rtx 3090` to append `#nvidia #rtx3090` at the end of the tweet.
* `include_regex` (optional): include products with a name matching this regexp
* `exclude_regex` (optional): exclude products with a name matching this regexp
* `browser_address` (optional): set headless browser address (ex: `http://127.0.0.1:9222`)
2020-12-27 18:27:07 +01:00
## How to contribute
2020-12-27 18:27:07 +01:00
Lint the code with pre-commit:
2020-12-27 18:27:07 +01:00
```
docker run -it -v $(pwd):/mnt/ --rm golang:latest bash
go get -u golang.org/x/lint/golint
apt-get update && apt-get upgrade -y && apt-get install -y git python3-pip
2020-12-27 18:27:07 +01:00
pip3 install pre-commit
cd /mnt
pre-commit run --all-files
```
## How to parse a shop
### Create the Ferret query
`RestockBot` uses [Ferret](https://github.com/MontFerret/ferret) and its FQL (Ferret Query Language) to parse websites. The full documentation is available [here](https://www.montferret.dev/docs/introduction/). Once installed, this library can be used as a CLI command or embedded in the application. To create the query, we can use the CLI for fast iterations, then we'll integrate the query in `RestockBot` later.
```
vim shop.fql
ferret --cdp http://127.0.0.1:9222 -time shop.fql
```
The query must return a list of products in JSON format with the following elements:
* `name`: string
* `url`: string
* `price`: float
* `price_currency`: string
* `available`: boolean
Example:
```json
[
{
"available": false,
"name": "Zotac GeForce RTX 3070 AMP Holo",
"price": 799.99,
"price_currency": "EUR",
"url": "https://www.topachat.com/pages/detail2_cat_est_micro_puis_rubrique_est_wgfx_pcie_puis_ref_est_in20007322.html"
},
{
"available": false,
"name": "Asus GeForce RTX 3070 DUAL 8G",
"price": 739.99,
"price_currency": "EUR",
"url": "https://www.topachat.com/pages/detail2_cat_est_micro_puis_rubrique_est_wgfx_pcie_puis_ref_est_in20005540.html"
},
{
"available": false,
"name": "Palit GeForce RTX 3070 GamingPro OC",
"price": 819.99,
"price_currency": "EUR",
"url": "https://www.topachat.com/pages/detail2_cat_est_micro_puis_rubrique_est_wgfx_pcie_puis_ref_est_in20005819.html"
}
]
```
`RestockBot` will convert this JSON to a list of `Product`.
### Embed the query
Shops are configured as a list of URLs:
```json
{
"urls": [
"https://www.topachat.com/pages/produits_cat_est_micro_puis_rubrique_est_wgfx_pcie_puis_f_est_58-11447,11445,11446,11559,11558.html",
"https://www.ldlc.com/informatique/pieces-informatique/carte-graphique-interne/c4684/+fv121-19183,19184,19185,19339,19340.html",
"https://www.materiel.net/carte-graphique/l426/+fv121-19183,19184,19185,19339,19340/"
]
}
```
The `Parse` function ([parser.go](parser.go)) will be called. In this example, the following **shop names** will be deduced: `topachat.com`, `ldlc.com` and `materiel.net`.
Each shop should implement a function to create a ferret query based on an URL:
* `func createQueryForLDLC(url string) string`
* `func createQueryForMaterielNet(url string) string`
* `func createQueryForTopachat(url string) string`
* ...
This function should be added to the switch of the `createQuery` function ([parser.go](parser.go)).
2020-12-27 18:27:07 +01:00
Products will then be parsed.
2020-12-27 18:27:07 +01:00
## Disclaimer
2020-12-27 18:27:07 +01:00
Crawling a website should be used with caution. Please check with retailers if the bot respects the terms of use for their websites. Authors of the bot are not responsible of the bot usage.