diff --git a/Dockerfile b/Dockerfile index 778bcfd..10e6137 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,21 +4,12 @@ FROM node:18 # Set the working directory in the container WORKDIR /usr/src/microsoft-rewards-script -# Install jq -RUN apt-get update && apt-get install -y jq - +# Install jq, cron, and gettext-base +RUN apt-get update && apt-get install -y jq cron gettext-base # Copy all files to the working directory COPY . . -# Check if "headless" is set to "true" in the config.json file -# DELETE BELOW IF YOU WANT TO RUN THE DOCKER SCRIPT HEADFULL! -RUN HEADLESS=$(cat src/config.json | jq -r .headless) \ - && if [ "$HEADLESS" != "true" ]; then \ - echo "Error: 'headless' in src/config.json is not true."; \ - exit 1; \ - fi - # Install dependencies including Playwright RUN apt-get install -y \ xvfb \ @@ -39,5 +30,11 @@ RUN npm run build # Install playwright chromium RUN npx playwright install chromium -# Define the command to run your application -CMD ["npm", "start"] +# Copy cron file to cron directory +COPY src/crontab.template /etc/cron.d/microsoft-rewards-cron.template + +# Create the log file to be able to run tail +RUN touch /var/log/cron.log + +# Define the command to run your application with cron optionally +CMD sh -c 'echo "$TZ" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata && if [ "$RUN_ON_START" = "true" ]; then npm start; fi && envsubst < /etc/cron.d/microsoft-rewards-cron.template > /etc/cron.d/microsoft-rewards-cron && crontab /etc/cron.d/microsoft-rewards-cron && cron && tail -f /var/log/cron.log' \ No newline at end of file diff --git a/README.md b/README.md index c565c03..7755b53 100644 --- a/README.md +++ b/README.md @@ -18,48 +18,65 @@ Under development, however mainly for personal use! ## Docker (Experimental) ## 1. Download the source code 2. Make changes to your `accounts.json` -3. Make sure to change `"headless": false` to `"headless": true` in your `config.json` -4. Note, the container has to be recreated for any changes regarding the `config.json` and/or `accounts.json`! +3. **Headless mode must be enabled when using Docker.** You can do this using the `HEADLESS=true` environmental variable in docker run or docker compose.yaml (see below). Environmental variables are always prioritized over the values in config.json. +4. The container will run scheduled. Customize your schedule using the `CRON_START_TIME` environmental variable. Use [crontab.guru](crontab.guru) if you're unsure how to create a cron schedule. +5. **Note:** the container will add between 5 and 50 minutes of randomized variability to your scheduled start times. ### Option 1: build and run with docker run -1. Run `docker build -t microsoft-rewards-script-docker .` to build the container -2. Run the container with `docker run --name netsky -d microsoft-rewards-script-docker` or, omit the detached flag `-d` to view the script output in your terminal. -3. Optionally, change the name of the container by changing `--name netsky` to your preferred container name -4. The container will exit after completing the script, run it again using `docker start netsky` -5. If you are running the container `-d` detached, you can view logs with `docker logs netsky` +1. Build or re-build the container image with: `docker build -t microsoft-rewards-script-docker .` + +2. Run the container with: + + ```bash + docker run --name netsky -d \ + -e TZ=America/New_York \ + -e HEADLESS=true \ + -e SEARCH_DELAY_MIN=10000 \ + -e SEARCH_DELAY_MAX=20000 \ + -e CLUSTERS=1 \ + -e CRON_START_TIME="0 5,11 * * *" \ + microsoft-rewards-script-docker + ``` + +3. Optionally, change any environmental variables other than `HEADLESS`, which must stay `=true` + +4. You can view logs with `docker logs netsky`. ### Option 2: use docker compose -1. A basic docker compose.yaml has been provided, which can be run with `docker compose up -d` or, omit the detached flag `-d` to view the script output in your terminal. +1. A basic docker compose.yaml has been provided. -2. The container will exit after completing the script, run it again using `docker start netsky` +2. Optionally, change any environmental variables other than `HEADLESS`, which must stay `=true` -3. If you are running the container `-d` detached, you can view logs with `docker logs netsky` +3. Build or rebuild and start the container using `docker compose up -d --build` + +4. You can view logs with `docker logs netsky` - ## Config ## -| Setting | Description | Default | -| :------------- |:-------------| :-----| -| baseURL | MS Rewards page | `https://rewards.bing.com` | -| sessionPath | Path to where you want sessions/fingerprints to be stored | `sessions` (In ./browser/sessions) | -| headless | If the browser window should be visible be ran in the background | `false` (Browser is visible) | -| runOnZeroPoints | Run the rest of the script if 0 points can be earned | `false` (Will not run on 0 points) | -| clusters | Amount of instances ran on launch, 1 per account | `1` (Will run 1 account at the time) | -| saveFingerprint | Re-use the same fingerprint each time | `false` (Will generate a new fingerprint each time) | -| workers.doDailySet | Complete daily set items | `true` | -| workers.doMorePromotions | Complete promotional items | `true` | -| workers.doPunchCards | Complete punchcards | `true` | -| workers.doDesktopSearch | Complete daily desktop searches | `true` | -| workers.doMobileSearch | Complete daily mobile searches | `true` | -| globalTimeout | The length before the action gets timeout | `30000` (30 seconds) | -| searchSettings.useGeoLocaleQueries | Generate search queries based on your geo-location | `false` (Uses EN-US generated queries) | -| scrollRandomResults | Scroll randomly in search results | `true` | -| searchSettings.clickRandomResults | Visit random website from search result| `true` | -| searchSettings.searchDelay | Minimum and maximum time in miliseconds between search queries | `min: 10000` (10 seconds) `max: 20000` (20 seconds) | -| searchSettings.retryMobileSearch | Keep retrying mobile searches until completed (indefinite)| `false` | -| webhook.enabled | Enable or disable your set webhook | `false` | -| webhook.url | Your Discord webhook URL | `null` | +| Setting | Description | Default | Docker Environmental Variable | +| :------------- |:-------------| :-----| :-----| +| baseURL | MS Rewards page | `https://rewards.bing.com` | BASE_URL | +| sessionPath | Path to where you want sessions/fingerprints to be stored | `sessions` (In ./browser/sessions) | SESSION_PATH | +| headless | If the browser window should be visible be ran in the background | `false` (Browser is visible) | HEADLESS *(must be set to `=true` for docker)* | +| runOnZeroPoints | Run the rest of the script if 0 points can be earned | `false` (Will not run on 0 points) | RUN_ON_ZERO_POINTS | +| clusters | Amount of instances ran on launch, 1 per account | `1` (Will run 1 account at the time) | CLUSTERS | +| saveFingerprint | Re-use the same fingerprint each time | `false` (Will generate a new fingerprint each time) | SAVE_FINGERPRINT | +| workers.doDailySet | Complete daily set items | `true` | WORKERS_DO_DAILY_SET | +| workers.doMorePromotions | Complete promotional items | `true` | WORKERS_DO_MORE_PROMOTIONS | +| workers.doPunchCards | Complete punchcards | `true` | WORKERS_DO_PUNCH_CARDS | +| workers.doDesktopSearch | Complete daily desktop searches | `true` | WORKERS_DO_DESKTOP_SEARCH | +| workers.doMobileSearch | Complete daily mobile searches | `true` | WORKERS_DO_MOBILE_SEARCH | +| globalTimeout | The length before the action gets timeout | `30000` (30 seconds) | GLOBAL_TIMEOUT | +| searchSettings.useGeoLocaleQueries | Generate search queries based on your geo-location | `false` (Uses EN-US generated queries) | SEARCH_SETTINGS_USE_GEO_LOCALE_QUERIES | +| scrollRandomResults | Scroll randomly in search results | `true` | SEARCH_SETTINGS_SCROLL_RANDOM_RESULTS | +| searchSettings.clickRandomResults | Visit random website from search result| `true` | SEARCH_SETTINGS_CLICK_RANDOM_RESULTS | +| searchSettings.searchDelay | Minimum and maximum time in miliseconds between search queries | `min: 10000` (10 seconds) `max: 20000` (20 seconds) | SEARCH_DELAY_MIN SEARCH_DELAY_MAX | +| searchSettings.retryMobileSearch | Keep retrying mobile searches until completed (indefinite)| `false` | SEARCH_SETTINGS_RETRY_MOBILE_SEARCH | +| webhook.enabled | Enable or disable your set webhook | `false` | WEBHOOK_ENABLED | +| webhook.url | Your Discord webhook URL | `null` | WEBHOOK_URL="" | +| cronStartTime | Scheduled script run-time, *only available for docker implementation* | `0 5,11 * * *` (5:00 am, 11:00 am daily) | CRON_START_TIME="" | +| | Run the script immediately when the Docker container starts | `true` | RUN_ON_START | ## Features ## - [x] Multi-Account Support @@ -87,6 +104,8 @@ Under development, however mainly for personal use! - [ ] Completing Gaming Tab - [x] Clustering Support - [x] Proxy Support +- [x] Docker Support (experimental) +- [x] Automatic scheduling (via Docker) ## Disclaimer ## Your account may be at risk of getting banned or suspended using this script, you've been warned! diff --git a/compose.yaml b/compose.yaml index b0d46a0..4d5a00f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -3,6 +3,32 @@ services: build: . container_name: netsky environment: - - NODE_ENV=production + - TZ=America/Toronto #change to your local timezone + - NODE_ENV=production + - HEADLESS=true #do not change + ### the following are optional, you only need to include them if you want to enter a custom value, removing them will use the default values + - BASE_URL=https://rewards.bing.com + - SESSION_PATH=sessions + - RUN_ON_ZERO_POINTS=false + - CLUSTERS=1 + - SAVE_FINGERPRINT=false + - WORKERS_DO_DAILY_SET=true + - WORKERS_DO_MORE_PROMOTIONS=true + - WORKERS_DO_PUNCH_CARDS=true + - WORKERS_DO_DESKTOP_SEARCH=true + - WORKERS_DO_MOBILE_SEARCH=true + - SEARCH_SETTINGS_USE_GEO_LOCALE_QUERIES=false + - SEARCH_SETTINGS_SCROLL_RANDOM_RESULTS=true + - SEARCH_SETTINGS_CLICK_RANDOM_RESULTS=true + - SEARCH_SETTINGS_SEARCH_DELAY_MIN=10000 # Set the search delay longer, e.g. MIN=180000 and MAX=270000 if you live in a region where MS enforces a search cooldown + - SEARCH_SETTINGS_SEARCH_DELAY_MAX=20000 + - SEARCH_SETTINGS_RETRY_MOBILE_SEARCH=true + - WEBHOOK_ENABLED=false + - WEBHOOK_URL= + ### Customize your run schedule, default 5:00 am and 11:00 am, use crontab.guru if you're not sure + - CRON_START_TIME=0 5,11 * * * + ### Run on start, set as false to only run the script per the cron schedule + - RUN_ON_START=true + restart: unless-stopped volumes: - .:/usr/src/microsoft-rewards-script diff --git a/src/config.json b/src/config.json index a73f173..c5d1509 100644 --- a/src/config.json +++ b/src/config.json @@ -26,5 +26,6 @@ "webhook": { "enabled": false, "url": "" - } + }, + "cronStartTime": "0 5,11 * * *" } \ No newline at end of file diff --git a/src/crontab.template b/src/crontab.template new file mode 100644 index 0000000..16de9ea --- /dev/null +++ b/src/crontab.template @@ -0,0 +1 @@ +${CRON_START_TIME} /bin/bash /usr/src/microsoft-rewards-script/src/run_daily.sh >> /var/log/cron.log 2>&1 diff --git a/src/run_daily.sh b/src/run_daily.sh new file mode 100644 index 0000000..15972ed --- /dev/null +++ b/src/run_daily.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Set up environment variables +export PATH=$PATH:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin + +# Change directory to the application directory +cd /usr/src/microsoft-rewards-script + +# Define the minimum and maximum wait times in seconds +MINWAIT=$((5*60)) # 5 minutes +MAXWAIT=$((50*60)) # 50 minutes + +# Calculate a random sleep time within the specified range +SLEEPTIME=$((MINWAIT + RANDOM % (MAXWAIT - MINWAIT))) + +# Convert the sleep time to minutes for logging +SLEEP_MINUTES=$((SLEEPTIME / 60)) + +# Log the sleep duration +echo "Sleeping for $SLEEP_MINUTES minutes ($SLEEPTIME seconds)..." + +# Sleep for the calculated time +sleep $SLEEPTIME + +# Log the start of the script +echo "Starting script..." + +# Execute the Node.js script directly +npm run start