DoujinStars
João Dias
João Dias

patreon


Doing stuff in JavaScript in Tasker is fun!!

Yesterday I posted a task that could get the full collection of Xbox Game Pass games and show it in a dialog .

I did that by using the AutoTools HTML Read action in a loop, to read all 3 pages of games, and then used AutoTools JSON Write to put that all in a single variable.

Then I used AutoTools JSON Read to read from the game list and finally an AutoTools Dialog to show them.

This is great, and shows how with little programming skills you can easily achieve something quite impressive using AutoTools :)

But Javascript is so fun that I had to have a go at doing the same with it! So this is what I came up with.


- I created an html file on my PC called test.html

- I simply added a <script type="text/javascript"></script> tag and didn't bother with the rest

- I started building a script to fetch the data from the Xbox website and put it in a JSON string, just as I did before with AutoTools

- I used several recent additions to JavaScript like arrow functions and async functions

- After everything was working I copy-pasted the script into a Tasker JavaScriptlet action and it all worked! :D No bugs or anything! It was a pleasant surprise, since I had never used JavaScript in Tasker before.


Here's the full code in case you're interested. To try it, open the file in Chrome on your PC and right-click the page -> inspect -> Console tab. You'll see the progress there.

You can also simply copy what's inside the script tag on the page into a  Tasker JavaScriptlet action  and then check the %XboxGamePass variable after the action runs. It should contain the full JSON!


Here's how the code works:


if(!window["setGlobal"]){
setGlobal = (name,value)=> console.log(`Setting global variable %${name} to ${value}`);
exit = () => console.log("Exiting...");
}

Checks if the setGlobal function exists, and if it doesn't, that means we're not in Tasker, so define placeholder functions for setGlobal and exit



if(!window["sortprop"]){
sortprop = "rating";
}

If the sortprop variable is not set, set it to rating. This will make the results sort by rating by default.




const sort = (array,selector,reverse) => array.sort((g1,g2)=> selector(g1) > selector(g2) ? (reverse?1:-1) : (reverse?-1:1))

Helper function to help sort the results.



Then there's a doIt() function that will fetch the results asynchronously. Inside it:


var result = [];
var skip = 180;

Initialize the final result variable and set the skip variable to 180. This will start fetching from the last page of the Xbox Game Pass game list. This is the page



while(skip >= 0){

Since each page has 90 games, the loop will go through page 3 (skip = 180), page 2 (skip = 90) and page 1 (skip = 0). After skip = 0 it exits the loop.



const url = `${baseUrl}${skip}`
skip = skip - 90;

Set the url for this iteration. It consists of the combination of the base url with the current skip number. Then subtract 90 to the current skip number so that the next iteration will run on the previous page of games.



const response = await fetch(url);
const text = await response.text();
const parsed = new window.DOMParser().parseFromString(text, "text/html");
       const array = Array.prototype.slice.call(parsed.querySelectorAll(".m-channel-placement-item"));

These 4 lines simply get the contents of the page, parse its html and put the results in an array. The array will contain a list of HTML elements with the class name .m-channel-placement-item which is the class name for each game on the html source of the page. Check out the source here for example and search for  .m-channel-placement-item . You'll see that each game has an html element with this class.



       const games = array.map(element=>{
    const s = selector => element.querySelector(selector);
    const t = selector => s(selector).innerText;
    const a = (selector,attribute) => s(selector).getAttribute(attribute);
    return {
    "name": t(".c-subheading-6"),
    "rating": parseFloat(t(`[itemprop="ratingValue"`)),
    "nrRatings": parseInt(t(`[itemprop="reviewCount"`).replace("K","000")),
    "link": `https://www.microsoft.com${a("a","href")}`,
    "icon": a("img","data-src")
    }
    });

This constructs an array of games from the array of HTML elements fetched above. s, t and a are helper functions to more easily get element values, and then we select each value (name, rating, nrRatings, link and icon) from each of the HTML elements.



    result = result.concat(games);

Add the currently fetched games to the final list of results.




result = sort(result,game=>game[sortprop],false);
setGlobal("GamePassJson",JSON.stringify(result));
exit();

After the loop is done and all games are fetched, we sort the results based on the sortprop variable, set the global variable in Tasker and exit the script! We're done! :)


Hope this can help people out or help people use JavaScript in cool ways with Tasker! :)

Let me know if you need any extra explanations!


More Creators