Skip to content

Instantly share code, notes, and snippets.

@masterflitzer
Last active June 25, 2023 15:14
Show Gist options
  • Save masterflitzer/d36e6a5432efdc1e5f51b5d3a7463b5d to your computer and use it in GitHub Desktop.
Save masterflitzer/d36e6a5432efdc1e5f51b5d3a7463b5d to your computer and use it in GitHub Desktop.
HelloFresh: Download all recipes of your past deliveries (bookmarklet)

HelloFresh Recipe Downloader

  • Go to past deliveries on HelloFresh: US | DE
  • Create a bookmark in your browser and paste javascript: followed by the minified code into the URL input field (Bookmarklet)
  • Alternatively: Open the browser DevTools (F12) and paste the code into the console

Minify

terser --compress --mangle --output hellofresh-recipe-downloader.min.js hellofresh-recipe-downloader.js
(() => {
"use strict";
if (document.readyState !== "complete") {
globalThis.addEventListener("load", () => main());
} else main();
async function main() {
const consolePrefix = "HelloFresh Recipe Downloader:";
const ratingCloseBtn = document.querySelector(
'button[data-test-id="rating-nudge-dismiss"]'
);
if (ratingCloseBtn != null) {
ratingCloseBtn.click();
}
const root = document
.querySelector("#root")
.querySelector(`div[data-test-id="past-deliveries"]`);
let pastDeliveriesShowMore = true;
while (pastDeliveriesShowMore) {
const pastDeliveriesShowMoreBtn = root.querySelector(
`button[data-test-id="past-deliveries-show-more-button"]`
);
pastDeliveriesShowMore = pastDeliveriesShowMoreBtn != null;
if (pastDeliveriesShowMore) {
pastDeliveriesShowMoreBtn.click();
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
const pastDeliveries = Array.from(
root.querySelectorAll(
`div[data-test-id^="past-delivery-container-"]`
)
)
.map((x) => Array.from(x.lastElementChild.children))
.flat(1);
const recipeCount = pastDeliveries.length;
console.info(`${consolePrefix} Found ${recipeCount} recipes`);
let recipeCounterSuccess = 0;
let recipeCounterFailure = 0;
for (const d of pastDeliveries) {
const recipeBtn = d.querySelector(
'button[data-test-id="recipe-body"]'
);
if (recipeBtn == null) continue;
recipeBtn.click();
await new Promise((resolve) => setTimeout(resolve, 1000));
const recipe = document.querySelector("#recipe-preview-modal");
const recipeTitle = recipe.querySelector(
'[data-test-id="recipe-preview-title"]'
).textContent;
const recipeDownload = recipe.querySelector('a[href$=".pdf"]');
if (recipeDownload != null) {
recipeCounterSuccess += 1;
console.info(
`${consolePrefix} Downloading recipe "${recipeTitle}"`
);
recipeDownload.click();
} else {
recipeCounterFailure += 1;
console.warn(
`${consolePrefix} There is no download available for recipe "${recipeTitle}"`
);
continue;
}
const closeBtn = recipe.querySelector(
'button[data-test-id="recipe-preview-close-button"]'
);
if (closeBtn == null) continue;
closeBtn.click();
}
console.info(
`${consolePrefix} ${recipeCounterSuccess} successful recipes`
);
console.info(`${consolePrefix} ${recipeCounterFailure} failed recipes`);
const recipeCounterSkipped =
recipeCount - (recipeCounterSuccess + recipeCounterFailure);
console.info(
`${consolePrefix} ${recipeCounterSkipped} skipped recipes`
);
}
})();
(()=>{"use strict";async function e(){const e="HelloFresh Recipe Downloader:",t=document.querySelector('button[data-test-id="rating-nudge-dismiss"]');null!=t&&t.click();const o=document.querySelector("#root").querySelector('div[data-test-id="past-deliveries"]');let i=!0;for(;i;){const e=o.querySelector('button[data-test-id="past-deliveries-show-more-button"]');i=null!=e,i&&(e.click(),await new Promise((e=>setTimeout(e,1e3))))}const n=Array.from(o.querySelectorAll('div[data-test-id^="past-delivery-container-"]')).map((e=>Array.from(e.lastElementChild.children))).flat(1),c=n.length;console.info(`${e} Found ${c} recipes`);let l=0,r=0;for(const t of n){const o=t.querySelector('button[data-test-id="recipe-body"]');if(null==o)continue;o.click(),await new Promise((e=>setTimeout(e,1e3)));const i=document.querySelector("#recipe-preview-modal"),n=i.querySelector('[data-test-id="recipe-preview-title"]').textContent,c=i.querySelector('a[href$=".pdf"]');if(null==c){r+=1,console.warn(`${e} There is no download available for recipe "${n}"`);continue}l+=1,console.info(`${e} Downloading recipe "${n}"`),c.click();const s=i.querySelector('button[data-test-id="recipe-preview-close-button"]');null!=s&&s.click()}console.info(`${e} ${l} successful recipes`),console.info(`${e} ${r} failed recipes`);const s=c-(l+r);console.info(`${e} ${s} skipped recipes`)}"complete"!==document.readyState?globalThis.addEventListener("load",(()=>e())):e()})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment