From f0e0e20c1feaec6878852a441ae2197f1e64c339 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 18:25:40 -0600 Subject: [PATCH 1/6] Template for displaying streams that were live at build time --- .gitignore | 3 ++- package.json | 5 +++- src/_data/streamers.json | 14 +++++++++++ src/live/index.liquid | 37 +++++++++++++++++++++++++++++ src/live/live.11tydata.js | 50 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/_data/streamers.json create mode 100644 src/live/index.liquid create mode 100644 src/live/live.11tydata.js diff --git a/.gitignore b/.gitignore index ccd37ad..e906dad 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ package-lock.json _site/ .idea/ **/.DS_Store -.cache \ No newline at end of file +.cache +.env \ No newline at end of file diff --git a/package.json b/package.json index 7e6b025..024ff1a 100644 --- a/package.json +++ b/package.json @@ -14,18 +14,21 @@ "dependencies": { "@11ty/eleventy": "^0.11.1", "@11ty/eleventy-cache-assets": "^2.3.0", + "axios": "^0.24.0", "calendar-link": "^2.0.8", "cross-env": "^7.0.3", "date-fns": "^2.16.1", "generate-comparators": "^1.0.3", "markdown-it": "^12.0.4", - "markdown-it-emoji": "^2.0.0" + "markdown-it-emoji": "^2.0.0", + "querystring": "^0.2.1" }, "devDependencies": { "@sherby/eleventy-plugin-files-minifier": "^1.1.1", "all-contributors-cli": "^6.19.0", "chalk": "^4.1.0", "commander": "^6.2.1", + "dotenv": "^10.0.0", "husky": "^4.3.6", "inquirer": "^7.3.3", "node-emoji": "^1.10.0", diff --git a/src/_data/streamers.json b/src/_data/streamers.json new file mode 100644 index 0000000..257133f --- /dev/null +++ b/src/_data/streamers.json @@ -0,0 +1,14 @@ +[ + "5t3phDev", + "BuildingBedrockLayout", + "jlengstorf", + "lunchdev", + "marbiano", + "SomeAnticsDev", + "stepzen_dev", + "ThoriumSim", + "TrostCodes", + "ManniMoki", + "mastermndio", + "loltyler1" +] diff --git a/src/live/index.liquid b/src/live/index.liquid new file mode 100644 index 0000000..71b02a4 --- /dev/null +++ b/src/live/index.liquid @@ -0,0 +1,37 @@ +--- +layout: layouts/page +--- +
{{ online | dump }}
+
+{% if online.size == 0 %} +

No one is streaming right now!

+

But check out some channels from around the community.

+ +{% elsif online.size == 1 %} +{% assign featuredChannel = online[0] %} +

{{ featuredChannel }} is streaming right now!

+{% twitch featuredChannel %} + +{% else %} +

{{ online.size }} community members are streaming right now!

+ +{% endif %} + +

Streamer List

+ diff --git a/src/live/live.11tydata.js b/src/live/live.11tydata.js new file mode 100644 index 0000000..ecf9896 --- /dev/null +++ b/src/live/live.11tydata.js @@ -0,0 +1,50 @@ +require('dotenv').config(); +const axios = require('axios'); +const qs = require('querystring'); + +let accessToken; + +/** + * Determines whether a given channel is streaming right now + * @param {string} channel + * @return {boolean} whether that channel is streaming + */ +async function isStreaming(channel) { + const { + data: { data: streams }, + } = await axios.get(`https://api.twitch.tv/helix/streams?user_login=${channel}`, { + headers: { + 'Client-ID': process.env.TWITCH_CLIENT_ID, + Authorization: `Bearer ${accessToken}`, + }, + }); + + return streams.length > 0; +} + +module.exports = { + eleventyComputed: { + online: async ({ streamers }) => { + const opts = { + client_id: process.env.TWITCH_CLIENT_ID, + client_secret: process.env.TWITCH_CLIENT_SECRET, + grant_type: 'client_credentials', + scopes: '', + }; + const params = qs.stringify(opts); + + const { data } = await axios.post(`https://id.twitch.tv/oauth2/token?${params}`); + accessToken = data.access_token; + + let activeStreamers = []; + for (let streamer of streamers) { + const live = await isStreaming(streamer); + if (live) { + activeStreamers.push(streamer); + } + } + + return activeStreamers; + }, + }, +}; From b80777e2d6bc04a3438253898c3d69fe1c3b9229 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 18:41:35 -0600 Subject: [PATCH 2/6] Upgrade to Eleventy v1 beta --- .eleventy.js | 6 +++ .gitignore | 4 +- netlify.toml | 9 +++- netlify/functions/onrequest/index.js | 55 +++++++++++++++++++++++ package.json | 2 +- src/_includes/layouts/event.html | 12 ++--- src/_includes/layouts/homepage.html | 8 ++-- src/_includes/layouts/page.html | 8 ++-- src/_includes/layouts/post.html | 4 +- src/_includes/partials/calendarLinks.html | 8 ++-- src/live/index.liquid | 1 - 11 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 netlify/functions/onrequest/index.js diff --git a/.eleventy.js b/.eleventy.js index 57a5f77..f5b17e0 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,3 +1,4 @@ +const { EleventyServerlessBundlerPlugin } = require('@11ty/eleventy'); const markdownIt = require('markdown-it'); const emoji = require('markdown-it-emoji'); const eleventyPluginFilesMinifier = require('@sherby/eleventy-plugin-files-minifier'); @@ -17,6 +18,11 @@ const isValidEvent = (event) => isValidTitle(event.data.title); const byDate = comparators((event) => event.data.date); module.exports = (eleventyConfig) => { + // eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, { + // name: 'onrequest', + // functionsDir: './netlify/functions/' + // }); + eleventyConfig.addCollection('events', (collectionApi) => { return collectionApi.getFilteredByGlob('./src/schedule/*.md'); }); diff --git a/.gitignore b/.gitignore index e906dad..dffd2a2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ _site/ .idea/ **/.DS_Store .cache -.env \ No newline at end of file +.env +netlify/functions/onrequest/** +!netlify/functions/onrequest/index.js \ No newline at end of file diff --git a/netlify.toml b/netlify.toml index c1017e0..aba5fe9 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,2 +1,9 @@ [build.environment] - TZ='America/Los_Angeles' \ No newline at end of file +TZ = "America/Los_Angeles" + +[[redirects]] +from = "/live/" +to = "/.netlify/functions/onrequest" +status = 200 +force = true +_generated_by_eleventy_serverless = "onrequest" diff --git a/netlify/functions/onrequest/index.js b/netlify/functions/onrequest/index.js new file mode 100644 index 0000000..56bfc8a --- /dev/null +++ b/netlify/functions/onrequest/index.js @@ -0,0 +1,55 @@ +const { EleventyServerless } = require('@11ty/eleventy'); + +// Explicit dependencies for the bundler from config file and global data. +// The file is generated by the Eleventy Serverless Bundler Plugin. +require('./eleventy-bundler-modules.js'); + +async function handler(event) { + let elev = new EleventyServerless('onrequest', { + path: event.path, + query: event.queryStringParameters, + functionsDir: './netlify/functions/', + }); + + try { + let [page] = await elev.getOutput(); + + // If you want some of the data cascade available in `page.data`, use `eleventyConfig.dataFilterSelectors`. + // Read more: https://www.11ty.dev/docs/config/#data-filter-selectors + + return { + statusCode: 200, + headers: { + 'Content-Type': 'text/html; charset=UTF-8', + }, + body: page.content, + }; + } catch (error) { + // Only console log for matching serverless paths + // (otherwise you’ll see a bunch of BrowserSync 404s for non-dynamic URLs during --serve) + if (elev.isServerlessUrl(event.path)) { + console.log('Serverless Error:', error); + } + + return { + statusCode: error.httpStatusCode || 500, + body: JSON.stringify( + { + error: error.message, + }, + null, + 2 + ), + }; + } +} + +// Choose one: +// * Runs on each request: AWS Lambda (or Netlify Function) +// * Runs on first request only: Netlify On-demand Builder +// (don’t forget to `npm install @netlify/functions`) + +exports.handler = handler; + +//const { builder } = require("@netlify/functions"); +//exports.handler = builder(handler); diff --git a/package.json b/package.json index 024ff1a..a0101a4 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "recognize": "all-contributors add" }, "dependencies": { - "@11ty/eleventy": "^0.11.1", + "@11ty/eleventy": "^1.0.0-beta.4", "@11ty/eleventy-cache-assets": "^2.3.0", "axios": "^0.24.0", "calendar-link": "^2.0.8", diff --git a/src/_includes/layouts/event.html b/src/_includes/layouts/event.html index 2064850..29f62f6 100644 --- a/src/_includes/layouts/event.html +++ b/src/_includes/layouts/event.html @@ -3,7 +3,7 @@ - {% include partials/favicon.html %} + {% include 'partials/favicon.html' %} @@ -30,10 +30,10 @@ - {% include partials/analytics.html %} + {% include 'partials/analytics.html' %} - {% include partials/header.html %} + {% include 'partials/header.html' %}

{{ title }}

@@ -43,7 +43,7 @@

{{ title }}

{% if calendarLinks.isPastEvent %} -
{% include partials/calendarLinks.html %}{% include partials/join-discord-button.html %}
+
{% include 'partials/calendarLinks.html' %}{% include 'partials/join-discord-button.html' %}
{% endif %} {{ content }} {% case speakers.size %} {% when undefined %} {% when 1 %}

Speaker

{% else %} @@ -101,8 +101,8 @@

Speakers

- {% include partials/event-sesh-command.html %} + {% include 'partials/event-sesh-command.html' %}
- {% include partials/footer.html %} + {% include 'partials/footer.html' %} diff --git a/src/_includes/layouts/homepage.html b/src/_includes/layouts/homepage.html index d4fa4c4..a1b4579 100644 --- a/src/_includes/layouts/homepage.html +++ b/src/_includes/layouts/homepage.html @@ -3,7 +3,7 @@ - {% include partials/favicon.html %} + {% include 'partials/favicon.html' %} @@ -17,10 +17,10 @@ /> Lunch.dev Community Calendar - {% include partials/analytics.html %} + {% include 'partials/analytics.html' %} - {% include partials/header.html %} + {% include 'partials/header.html' %}

Next event

@@ -113,6 +113,6 @@

{{ event.data.title }}

{% endfor %}
- {% include partials/footer.html %} + {% include 'partials/footer.html' %} diff --git a/src/_includes/layouts/page.html b/src/_includes/layouts/page.html index 392051a..27a32e8 100644 --- a/src/_includes/layouts/page.html +++ b/src/_includes/layouts/page.html @@ -3,7 +3,7 @@ - {% include partials/favicon.html %} + {% include 'partials/favicon.html' %} @@ -14,16 +14,16 @@ rel="stylesheet" /> {{ title }} | Lunch.dev Community Calendar - {% include partials/analytics.html %} + {% include 'partials/analytics.html' %} - {% include partials/header.html %} + {% include 'partials/header.html' %}

{{ title }}

{{ content }}
- {% include partials/footer.html %} + {% include 'partials/footer.html' %} diff --git a/src/_includes/layouts/post.html b/src/_includes/layouts/post.html index 652df84..73f1cbb 100644 --- a/src/_includes/layouts/post.html +++ b/src/_includes/layouts/post.html @@ -13,10 +13,10 @@ rel="stylesheet" /> {{ title }} | Lunch.dev Community Calendar - {% include partials/analytics.html %} + {% include 'partials/analytics.html' %} - {% include partials/header.html %} + {% include 'partials/header.html' %}

{{ title }}

diff --git a/src/_includes/partials/calendarLinks.html b/src/_includes/partials/calendarLinks.html index 511eba3..1840529 100644 --- a/src/_includes/partials/calendarLinks.html +++ b/src/_includes/partials/calendarLinks.html @@ -3,21 +3,21 @@
diff --git a/src/live/index.liquid b/src/live/index.liquid index 71b02a4..da28c02 100644 --- a/src/live/index.liquid +++ b/src/live/index.liquid @@ -1,7 +1,6 @@ --- layout: layouts/page --- -
{{ online | dump }}

{% if online.size == 0 %}

No one is streaming right now!

From cbc9421ac9fe25adad5b87ed3cb4aa137ac5656a Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 18:59:05 -0600 Subject: [PATCH 3/6] Unleash the serverless on the /live/ route --- .eleventy.js | 9 +++++---- src/live/index.liquid | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.eleventy.js b/.eleventy.js index f5b17e0..5ad0dfa 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -18,10 +18,11 @@ const isValidEvent = (event) => isValidTitle(event.data.title); const byDate = comparators((event) => event.data.date); module.exports = (eleventyConfig) => { - // eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, { - // name: 'onrequest', - // functionsDir: './netlify/functions/' - // }); + eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, { + name: 'onrequest', + functionsDir: './netlify/functions/', + copy: ['src/utils/'], + }); eleventyConfig.addCollection('events', (collectionApi) => { return collectionApi.getFilteredByGlob('./src/schedule/*.md'); diff --git a/src/live/index.liquid b/src/live/index.liquid index da28c02..0f69160 100644 --- a/src/live/index.liquid +++ b/src/live/index.liquid @@ -1,7 +1,9 @@ --- +title: Community Streamers layout: layouts/page +permalink: + onrequest: /live/ --- -
{% if online.size == 0 %}

No one is streaming right now!

But check out some channels from around the community.

From 9bf8c1fec09622a2174b21e8a39f5b206b5ef441 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 19:03:26 -0600 Subject: [PATCH 4/6] Remove test streamers --- src/_data/streamers.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/_data/streamers.json b/src/_data/streamers.json index 257133f..1786f8e 100644 --- a/src/_data/streamers.json +++ b/src/_data/streamers.json @@ -7,8 +7,5 @@ "SomeAnticsDev", "stepzen_dev", "ThoriumSim", - "TrostCodes", - "ManniMoki", - "mastermndio", - "loltyler1" + "TrostCodes" ] From 83ceab052fcb67a29ee0ef4b6bdb6e41bf31b013 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 19:20:35 -0600 Subject: [PATCH 5/6] Don't require client ID --- src/_data/streamers.json | 4 ++-- src/live/live.11tydata.js | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/_data/streamers.json b/src/_data/streamers.json index 1786f8e..7fca162 100644 --- a/src/_data/streamers.json +++ b/src/_data/streamers.json @@ -1,11 +1,11 @@ [ "5t3phDev", "BuildingBedrockLayout", - "jlengstorf", "lunchdev", "marbiano", "SomeAnticsDev", "stepzen_dev", "ThoriumSim", - "TrostCodes" + "TrostCodes", + "mastermndio" ] diff --git a/src/live/live.11tydata.js b/src/live/live.11tydata.js index ecf9896..b735567 100644 --- a/src/live/live.11tydata.js +++ b/src/live/live.11tydata.js @@ -1,4 +1,3 @@ -require('dotenv').config(); const axios = require('axios'); const qs = require('querystring'); @@ -25,6 +24,10 @@ async function isStreaming(channel) { module.exports = { eleventyComputed: { online: async ({ streamers }) => { + if (!process.env.TWITCH_CLIENT_ID) { + return []; + } + const opts = { client_id: process.env.TWITCH_CLIENT_ID, client_secret: process.env.TWITCH_CLIENT_SECRET, From 1d888174ad0351d5dcff889c7aa550562721bab6 Mon Sep 17 00:00:00 2001 From: Ben Myers Date: Mon, 8 Nov 2021 21:21:49 -0600 Subject: [PATCH 6/6] Pivot to 1.0.0-beta.3 --- netlify/functions/onrequest/index.js | 7 +------ package.json | 2 +- src/_data/streamers.json | 3 +-- src/live/live.11tydata.js | 1 + 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/netlify/functions/onrequest/index.js b/netlify/functions/onrequest/index.js index 56bfc8a..629190b 100644 --- a/netlify/functions/onrequest/index.js +++ b/netlify/functions/onrequest/index.js @@ -12,17 +12,12 @@ async function handler(event) { }); try { - let [page] = await elev.getOutput(); - - // If you want some of the data cascade available in `page.data`, use `eleventyConfig.dataFilterSelectors`. - // Read more: https://www.11ty.dev/docs/config/#data-filter-selectors - return { statusCode: 200, headers: { 'Content-Type': 'text/html; charset=UTF-8', }, - body: page.content, + body: await elev.render(), }; } catch (error) { // Only console log for matching serverless paths diff --git a/package.json b/package.json index a0101a4..f048f35 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "recognize": "all-contributors add" }, "dependencies": { - "@11ty/eleventy": "^1.0.0-beta.4", + "@11ty/eleventy": "1.0.0-beta.3", "@11ty/eleventy-cache-assets": "^2.3.0", "axios": "^0.24.0", "calendar-link": "^2.0.8", diff --git a/src/_data/streamers.json b/src/_data/streamers.json index 7fca162..1f39dae 100644 --- a/src/_data/streamers.json +++ b/src/_data/streamers.json @@ -6,6 +6,5 @@ "SomeAnticsDev", "stepzen_dev", "ThoriumSim", - "TrostCodes", - "mastermndio" + "TrostCodes" ] diff --git a/src/live/live.11tydata.js b/src/live/live.11tydata.js index b735567..f22ed09 100644 --- a/src/live/live.11tydata.js +++ b/src/live/live.11tydata.js @@ -1,3 +1,4 @@ +// require('dotenv').config(); const axios = require('axios'); const qs = require('querystring');