Avatar

dazzag24

Joined June 27, 2024
Public vals
1
dazzag24 avatar
dazzag24
zwiftPortalSchedule
Script
Fetch and parse the Zwift Climbing Portal Schedule XML from the Zwift CDN. Example usage: console.log(await zwiftPortalSchedule()); Expected output will look something like this: [ { "date": "Sun, Oct 27", "road": "La Turbie + Col d'Eze", "distance": "15.9km", "elevation": "616m", "gradient": "3.9%", "isPortalOfMonth": false, "world": "Watopia" }, { "date": "Mon, Oct 28", "road": "Col du Galibier (Lautaret)", "distance": "10.4km", "elevation": "539m", "gradient": "5.2%", "isPortalOfMonth": false, "world": "Watopia" }, { "date": "Thu, Oct 31", "road": "Mt. Hamilton", "distance": "31.3km", "elevation": "1259m", "gradient": "4.0%", "isPortalOfMonth": true, "world": "France" } ] Create a cron to send an email periodically: import { zwiftPortalSchedule } from "https://esm.town/v/dazzag24/zwiftPortalSchedule"; import { email } from "https://esm.town/v/std/email"; export default async function sendZwiftPortalSchedule(interval: Interval) { console.log("Parsing Zwift portal road schedule..."); const schedule = await zwiftPortalSchedule(); const content = schedule.map(event => `**${event.date}**\n${event.road}\nšŸ“ ${event.distance} | ā›°ļø ${event.elevation} | šŸ“ˆ ${event.gradient}${ event.isPortalOfMonth ? " | šŸ† Portal of the Month" : "" }\nšŸŒ ${event.world}\n` ).join("\n"); console.log(content); return email({ subject: "Zwift Climbing Portal Schedule", text: "**Upcoming Zwift Portal Roads**\n\n" + content, }); }
0
Next