Skip to content

Instantly share code, notes, and snippets.

@devonChurch
Last active April 20, 2021 07:10
Show Gist options
  • Select an option

  • Save devonChurch/dfa838a12d9dd08d1f68a7e4f36e452d to your computer and use it in GitHub Desktop.

Select an option

Save devonChurch/dfa838a12d9dd08d1f68a7e4f36e452d to your computer and use it in GitHub Desktop.

Revisions

  1. devonChurch revised this gist Apr 20, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.js
    Original file line number Diff line number Diff line change
    @@ -7,9 +7,9 @@ const API_METHOD = "nz.co.LanguagePerfect.Services.PortalsAsync.ControlPanel.New
    const FIRESTORE_COLLECTION = "testimonialsFiltered";
    const FIRESTORE_PROJECT_ID = "testimonials-4d1e6";
    const COUNTRIES = [
    1, // Australia,
    1, // International,
    2, // New Zealand
    3, // International
    3, // Australia
    ];

    /**
  2. devonChurch created this gist Apr 18, 2021.
    96 changes: 96 additions & 0 deletions index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    const Firestore = require("@google-cloud/firestore");
    const functions = require("firebase-functions");
    const axios = require("axios");

    const API_ENDPOINT = "https://services.languageperfect.com/json.rpc";
    const API_METHOD = "nz.co.LanguagePerfect.Services.PortalsAsync.ControlPanel.NewsPortal.GetCommunityArticlesPublic"; // prettier-ignore
    const FIRESTORE_COLLECTION = "testimonialsFiltered";
    const FIRESTORE_PROJECT_ID = "testimonials-4d1e6";
    const COUNTRIES = [
    1, // Australia,
    2, // New Zealand
    3, // International
    ];

    /**
    * Get as many testimonial items as we can that are associated with the supplied
    * `Country` code.
    *
    * @note We make sure to extract the items from the response payload before resolving
    * this async sequence.
    */
    const getRawitems = ({ Country }) =>
    axios
    .post(API_ENDPOINT, {
    method: API_METHOD,
    params: [
    {
    // @note We do not have an `Infinity` or "all" value here, so in order to get every item, we ask
    // for an enormous set and take the values that were used to attempt the quota.
    NumberOfArticles: 99999999,
    DepartmentIDs: [],
    Country,
    },
    ],
    })
    .then((response) => response.data.result.Articles);

    /**
    * Strip down the Back-end item structure to a reduced "slim" payload for the Front-end.
    */
    const sanitizeItems = (items) =>
    items.map((item) => ({
    // @note the original `ItemID` is changed to `id` when sanitising.
    id: item.ItemID,
    ...[
    "AuthorFirstName",
    "AuthorSurname",
    "CountryName",
    "ImageURL",
    "PlainTextMessage",
    "PostDate",
    "SchoolLatitude",
    "SchoolLongitude",
    "SchoolName",
    "StateAbbreviation",
    ].reduce((acc, key) => ({ ...acc, [key]: item[key] }), {}),
    }));

    /**
    * Setup and hold the testimonial collection in closure. `set` items onto the collection using their
    * `id` as the primary index.
    *
    * @note a `set` will either "update" or "create" an item if the `id` does not exist in the collection.
    *
    * @see https://firebase.google.com/docs/firestore/manage-data/add-data#set_a_document
    */
    const setItemInFirestore = (() => {
    const firestoreCollection = new Firestore({
    projectId: FIRESTORE_PROJECT_ID,
    }).collection(FIRESTORE_COLLECTION);

    return (item) => firestoreCollection.doc(`${item.id}`).set(item);
    })();

    const startSequence = async (context) => {
    try {
    // Get the testimonial items for each country (with independent async requests) and flatten the
    // responses into a single "sanitized" item list.
    const sanitizedItems = await Promise.all(
    COUNTRIES.map((Country) => getRawitems({ Country }))
    )
    .then((...rawItems) => rawItems.flat(Infinity))
    .then(sanitizeItems);

    // Iterate through our fetch/flattened/sanitised item list and "set" them into our Firestore
    await Promise.all(sanitizedItems.map(setItemInFirestore));
    } catch (error) {
    console.error(error);
    }
    };

    // @see https://firebase.google.com/docs/functions/schedule-functions
    // @see https://cloud.google.com/appengine/docs/standard/python/config/cronref
    exports.scheduledFunction = functions.pubsub
    .schedule("every 24 hours")
    .onRun(startSequence);