├── examples ├── instagram ├── twitter ├── spotify └── github ├── package.json ├── .glitch-assets ├── README.md ├── server.js └── shrinkwrap.yaml /examples/instagram: -------------------------------------------------------------------------------- 1 | ---|||layout: post|||title: {{Caption}} - Tweet|||network: instagram|||date: {{CreatedAt}}|||---|||{{EmbedCode}} -------------------------------------------------------------------------------- /examples/twitter: -------------------------------------------------------------------------------- 1 | ---|||layout: post|||title: {{UserName}} - Tweet|||network: twitter|||date: {{CreatedAt}}|||---|||{{TweetEmbedCode}} -------------------------------------------------------------------------------- /examples/spotify: -------------------------------------------------------------------------------- 1 | ---|||layout: post|||title: {{TrackName}}|||network: spotify|||date: {{AddedAt}}|||---|||<<<>>> -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "//1": "describes your app and its dependencies", 3 | "//2": "https://docs.npmjs.com/files/package.json", 4 | "//3": "updating this file will download and update your packages", 5 | "name": "my-glitch-app", 6 | "version": "0.0.1", 7 | "description": "What am I about?", 8 | "main": "server.js", 9 | "scripts": { 10 | "start": "node server.js" 11 | }, 12 | "dependencies": { 13 | "express": "^4.15.3", 14 | "body-parser": "^1.18.2", 15 | "moment": "^2.19.3", 16 | "chrono-node": "^1.3.5", 17 | "github": "^12.0.2" 18 | }, 19 | "engines": { 20 | "node": "8.1.x" 21 | }, 22 | "repository": { 23 | "url": "https://glitch.com/edit/#!/welcome-project" 24 | }, 25 | "license": "MIT", 26 | "keywords": [ 27 | "node", 28 | "glitch", 29 | "express" 30 | ] 31 | } -------------------------------------------------------------------------------- /.glitch-assets: -------------------------------------------------------------------------------- 1 | {"name":"drag-in-files.svg","date":"2016-10-22T16:17:49.954Z","url":"https://cdn.hyperdev.com/drag-in-files.svg","type":"image/svg","size":7646,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/drag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(102, 153, 205)","uuid":"adSBq97hhhpFNUna"} 2 | {"name":"click-me.svg","date":"2016-10-23T16:17:49.954Z","url":"https://cdn.hyperdev.com/click-me.svg","type":"image/svg","size":7116,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/click-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(243, 185, 186)","uuid":"adSBq97hhhpFNUnb"} 3 | {"name":"paste-me.svg","date":"2016-10-24T16:17:49.954Z","url":"https://cdn.hyperdev.com/paste-me.svg","type":"image/svg","size":7242,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/paste-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(42, 179, 185)","uuid":"adSBq97hhhpFNUnc"} 4 | {"uuid":"adSBq97hhhpFNUna","deleted":true} 5 | {"uuid":"adSBq97hhhpFNUnb","deleted":true} 6 | {"uuid":"adSBq97hhhpFNUnc","deleted":true} 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ifttt-ghpages 2 | 3 | Hello! 👋 This is a script which lets you create Jekyll entries in a Github repo from IFTTT events, using the IFTTT Webhook action. You can see it in use on [https://webrender.net](https://webrender.net). 4 | 5 | # Setup 6 | 7 | * [Remix this project](https://glitch.com/~ifttt-ghpages) (or [clone the repo](https://github.com/webrender/ifttt-ghpages) if you'd prefer to run it yourself) 8 | * in the .env file, enter your username, the repo you'd like to commit to, and your Github user token. You can generate a Personal Access Token for use with this script here: [https://github.com/settings/tokens](https://github.com/settings/tokens) 9 | * for the `WEBHOOK_TOKEN` env variable, generate/create a token of your choice. We'll use this to verify requests are coming from our webhook. 10 | * Go to IFTTT and create a new applet. For the "that" action, choose the `Webhooks` service, and then the `Make a web request` option. Fill in the fields as follows: 11 | * URL: The URL of your node server, with a `token` parameter. Example: 12 | * `https://ifttt-ghpages.glitch.me/?token=your-token` 13 | * Method: POST 14 | * Content Type: text/plain 15 | * Body: A YAML-formatted Jekyll document, with newlines replaced with `|||`. Example from `examples/twitter`: 16 | * `---|||layout: post|||title: {{UserName}} - Tweet|||network: twitter|||date: {{CreatedAt}}|||---|||{{TweetEmbedCode}}` -------------------------------------------------------------------------------- /examples/github: -------------------------------------------------------------------------------- 1 | ---|||layout: post|||network: github|||user: {{AuthorUsername}}|||repo: {{RepositoryName}}|||date: {{CreatedAt}}|||pr_title: {{PullRequestTitle}}|||pr_url: {{PullRequestURL}}|||title: {{PullRequestTitle}}|||tags:|||- IFTTT|||- Github|||---||| {{PullRequestBody}} 2 | 3 | post markup: 4 | 5 |
6 | {{ page.user }} created a pull request in {{ page.repo }} 7 |17 | 18 | 19 | post styles: 20 | 21 | blockquote.github-pull-request { 22 | background: #fdfdfd; 23 | border-radius: 3px; 24 | border: 1px solid #e1e8ed; 25 | padding: 15px; 26 | font-style: normal; 27 | font-size: 12px; 28 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 29 | letter-spacing: normal; 30 | 31 | p { 32 | margin-top: 5px; 33 | } 34 | 35 | h2, h2 a{ 36 | font-weight: bold; 37 | color: black; 38 | line-height: 22px; 39 | margin: 10px 0; 40 | } 41 | 42 | hr { 43 | border: none; 44 | border-top: 1px solid #e1e8ed; 45 | margin-bottom: 4px; 46 | } 47 | 48 | .gh-logo { 49 | height: 16px; 50 | width: 16px; 51 | float: right; 52 | margin: 0 4px; 53 | } 54 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // server.js 2 | // where your node app starts 3 | 4 | // init project 5 | var express = require('express'); 6 | var bodyParser = require('body-parser'); 7 | var moment = require('moment'); 8 | var chrono = require('chrono-node'); 9 | var app = express(); 10 | var GitHubApi = require('github'); 11 | var moment = require('moment'); 12 | 13 | var github = new GitHubApi(); 14 | 15 | app.use(bodyParser.text()); 16 | app.post("/", (req, res) => { 17 | if (req.query.token !== process.env.WEBHOOK_TOKEN) 18 | res.sendStatus(400); 19 | var body = req.body.replace(/\|\|\|/g, '\n'); 20 | body = body.replace('INSERT_DATE_HERE', moment(new Date()).subtract(10, 'hours').format("MMMM D, YYYY [at] HH:mmA")); 21 | console.log(body) 22 | if (body.includes('post via ifttt-ghpages')) { 23 | // don't post commits from this script, causing an infinite post loop 24 | res.sendStatus(200) 25 | } else { 26 | var title; 27 | var titleSearch = body.match(/title: (.*?)\n/); 28 | if (titleSearch && titleSearch.length > 0) { 29 | title = titleSearch[1]; 30 | } 31 | var dateSearch = body.match(/date: (.*?)\n/); 32 | var date = dateSearch[1] ? chrono.parseDate(dateSearch[1]) : new Date(); 33 | var networkSearch = body.match(/network: (.*?)\n/); 34 | if (networkSearch && networkSearch[1].includes('github_rss')) { 35 | var regex = /href="\/webrender/gi; 36 | body = body.replace(regex, 'href="https://github.com/webrender') 37 | } 38 | github.authenticate({ 39 | type: 'oauth', 40 | token: process.env.GH_TOKEN 41 | }) 42 | github.repos.createFile({ 43 | owner: process.env.GH_USER, 44 | repo: process.env.GH_REPO, 45 | path: `_posts/${moment(date).format('YYYY-MM-DD-HH-mm-ss-')}${title}.html`, 46 | message: 'post via ifttt-ghpages', 47 | content: new Buffer(body).toString('base64') 48 | }, function(err, resp) { 49 | if (err) { 50 | console.log('error: ' + err); 51 | res.sendStatus(500); 52 | } else { 53 | console.log('success: ' + resp); 54 | res.sendStatus(200); 55 | } 56 | }); 57 | } 58 | }); 59 | 60 | 61 | // listen for requests :) 62 | var listener = app.listen(process.env.PORT, function () { 63 | console.log('Your app is listening on port ' + listener.address().port); 64 | }); -------------------------------------------------------------------------------- /shrinkwrap.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | body-parser: 1.19.0 3 | chrono-node: 1.3.11 4 | express: 4.17.1 5 | github: 12.1.0 6 | moment: 2.24.0 7 | packages: 8 | /accepts/1.3.7: 9 | dependencies: 10 | mime-types: 2.1.25 11 | negotiator: 0.6.2 12 | dev: false 13 | engines: 14 | node: '>= 0.6' 15 | resolution: 16 | integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== 17 | /agent-base/4.3.0: 18 | dependencies: 19 | es6-promisify: 5.0.0 20 | dev: false 21 | engines: 22 | node: '>= 4.0.0' 23 | resolution: 24 | integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== 25 | /array-flatten/1.1.1: 26 | dev: false 27 | resolution: 28 | integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 29 | /body-parser/1.19.0: 30 | dependencies: 31 | bytes: 3.1.0 32 | content-type: 1.0.4 33 | debug: 2.6.9 34 | depd: 1.1.2 35 | http-errors: 1.7.2 36 | iconv-lite: 0.4.24 37 | on-finished: 2.3.0 38 | qs: 6.7.0 39 | raw-body: 2.4.0 40 | type-is: 1.6.18 41 | dev: false 42 | engines: 43 | node: '>= 0.8' 44 | resolution: 45 | integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== 46 | /bytes/3.1.0: 47 | dev: false 48 | engines: 49 | node: '>= 0.8' 50 | resolution: 51 | integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== 52 | /chrono-node/1.3.11: 53 | dependencies: 54 | moment: 2.21.0 55 | dev: false 56 | resolution: 57 | integrity: sha512-jDWRnY6nYvzfV3HPYBqo+tot7tcsUs9i3arGbMdI0TouPSXP2C2y/Ctp27rxKTQDi6yuTxAB2cw+Q6igGhOhdQ== 58 | /content-disposition/0.5.3: 59 | dependencies: 60 | safe-buffer: 5.1.2 61 | dev: false 62 | engines: 63 | node: '>= 0.6' 64 | resolution: 65 | integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== 66 | /content-type/1.0.4: 67 | dev: false 68 | engines: 69 | node: '>= 0.6' 70 | resolution: 71 | integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 72 | /cookie-signature/1.0.6: 73 | dev: false 74 | resolution: 75 | integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 76 | /cookie/0.4.0: 77 | dev: false 78 | engines: 79 | node: '>= 0.6' 80 | resolution: 81 | integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== 82 | /debug/2.6.9: 83 | dependencies: 84 | ms: 2.0.0 85 | dev: false 86 | resolution: 87 | integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 88 | /debug/3.2.6: 89 | dependencies: 90 | ms: 2.1.2 91 | dev: false 92 | resolution: 93 | integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 94 | /depd/1.1.2: 95 | dev: false 96 | engines: 97 | node: '>= 0.6' 98 | resolution: 99 | integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 100 | /destroy/1.0.4: 101 | dev: false 102 | resolution: 103 | integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 104 | /dotenv/4.0.0: 105 | dev: false 106 | engines: 107 | node: '>=4.6.0' 108 | resolution: 109 | integrity: sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0= 110 | /ee-first/1.1.1: 111 | dev: false 112 | resolution: 113 | integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 114 | /encodeurl/1.0.2: 115 | dev: false 116 | engines: 117 | node: '>= 0.8' 118 | resolution: 119 | integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 120 | /es6-promise/4.2.8: 121 | dev: false 122 | resolution: 123 | integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 124 | /es6-promisify/5.0.0: 125 | dependencies: 126 | es6-promise: 4.2.8 127 | dev: false 128 | resolution: 129 | integrity: sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 130 | /escape-html/1.0.3: 131 | dev: false 132 | resolution: 133 | integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 134 | /etag/1.8.1: 135 | dev: false 136 | engines: 137 | node: '>= 0.6' 138 | resolution: 139 | integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 140 | /express/4.17.1: 141 | dependencies: 142 | accepts: 1.3.7 143 | array-flatten: 1.1.1 144 | body-parser: 1.19.0 145 | content-disposition: 0.5.3 146 | content-type: 1.0.4 147 | cookie: 0.4.0 148 | cookie-signature: 1.0.6 149 | debug: 2.6.9 150 | depd: 1.1.2 151 | encodeurl: 1.0.2 152 | escape-html: 1.0.3 153 | etag: 1.8.1 154 | finalhandler: 1.1.2 155 | fresh: 0.5.2 156 | merge-descriptors: 1.0.1 157 | methods: 1.1.2 158 | on-finished: 2.3.0 159 | parseurl: 1.3.3 160 | path-to-regexp: 0.1.7 161 | proxy-addr: 2.0.5 162 | qs: 6.7.0 163 | range-parser: 1.2.1 164 | safe-buffer: 5.1.2 165 | send: 0.17.1 166 | serve-static: 1.14.1 167 | setprototypeof: 1.1.1 168 | statuses: 1.5.0 169 | type-is: 1.6.18 170 | utils-merge: 1.0.1 171 | vary: 1.1.2 172 | dev: false 173 | engines: 174 | node: '>= 0.10.0' 175 | resolution: 176 | integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== 177 | /finalhandler/1.1.2: 178 | dependencies: 179 | debug: 2.6.9 180 | encodeurl: 1.0.2 181 | escape-html: 1.0.3 182 | on-finished: 2.3.0 183 | parseurl: 1.3.3 184 | statuses: 1.5.0 185 | unpipe: 1.0.0 186 | dev: false 187 | engines: 188 | node: '>= 0.8' 189 | resolution: 190 | integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== 191 | /follow-redirects/1.2.6: 192 | dependencies: 193 | debug: 3.2.6 194 | dev: false 195 | engines: 196 | node: '>=4.0' 197 | resolution: 198 | integrity: sha512-FrMqZ/FONtHnbqO651UPpfRUVukIEwJhXMfdr/JWAmrDbeYBu773b1J6gdWDyRIj4hvvzQEHoEOTrdR8o6KLYA== 199 | /forwarded/0.1.2: 200 | dev: false 201 | engines: 202 | node: '>= 0.6' 203 | resolution: 204 | integrity: sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 205 | /fresh/0.5.2: 206 | dev: false 207 | engines: 208 | node: '>= 0.6' 209 | resolution: 210 | integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 211 | /github/12.1.0: 212 | dependencies: 213 | dotenv: 4.0.0 214 | follow-redirects: 1.2.6 215 | https-proxy-agent: 2.2.4 216 | lodash: 4.17.15 217 | mime: 2.4.4 218 | netrc: 0.1.4 219 | deprecated: '''github'' has been renamed to ''@octokit/rest'' (https://git.io/vNB11)' 220 | dev: false 221 | engines: 222 | node: '>=4' 223 | resolution: 224 | integrity: sha512-HhWjhd/OATC4Hjj7xfGjGRtwWzo/fzTc55EkvsRatI9G6Vp47mVcdBIt1lQ56A9Qit/yVQRX1+M9jbWlcJvgug== 225 | /http-errors/1.7.2: 226 | dependencies: 227 | depd: 1.1.2 228 | inherits: 2.0.3 229 | setprototypeof: 1.1.1 230 | statuses: 1.5.0 231 | toidentifier: 1.0.0 232 | dev: false 233 | engines: 234 | node: '>= 0.6' 235 | resolution: 236 | integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== 237 | /http-errors/1.7.3: 238 | dependencies: 239 | depd: 1.1.2 240 | inherits: 2.0.4 241 | setprototypeof: 1.1.1 242 | statuses: 1.5.0 243 | toidentifier: 1.0.0 244 | dev: false 245 | engines: 246 | node: '>= 0.6' 247 | resolution: 248 | integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== 249 | /https-proxy-agent/2.2.4: 250 | dependencies: 251 | agent-base: 4.3.0 252 | debug: 3.2.6 253 | dev: false 254 | engines: 255 | node: '>= 4.5.0' 256 | resolution: 257 | integrity: sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== 258 | /iconv-lite/0.4.24: 259 | dependencies: 260 | safer-buffer: 2.1.2 261 | dev: false 262 | engines: 263 | node: '>=0.10.0' 264 | resolution: 265 | integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 266 | /inherits/2.0.3: 267 | dev: false 268 | resolution: 269 | integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 270 | /inherits/2.0.4: 271 | dev: false 272 | resolution: 273 | integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 274 | /ipaddr.js/1.9.0: 275 | dev: false 276 | engines: 277 | node: '>= 0.10' 278 | resolution: 279 | integrity: sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== 280 | /lodash/4.17.15: 281 | dev: false 282 | resolution: 283 | integrity: sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 284 | /media-typer/0.3.0: 285 | dev: false 286 | engines: 287 | node: '>= 0.6' 288 | resolution: 289 | integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 290 | /merge-descriptors/1.0.1: 291 | dev: false 292 | resolution: 293 | integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 294 | /methods/1.1.2: 295 | dev: false 296 | engines: 297 | node: '>= 0.6' 298 | resolution: 299 | integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 300 | /mime-db/1.42.0: 301 | dev: false 302 | engines: 303 | node: '>= 0.6' 304 | resolution: 305 | integrity: sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== 306 | /mime-types/2.1.25: 307 | dependencies: 308 | mime-db: 1.42.0 309 | dev: false 310 | engines: 311 | node: '>= 0.6' 312 | resolution: 313 | integrity: sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== 314 | /mime/1.6.0: 315 | dev: false 316 | engines: 317 | node: '>=4' 318 | hasBin: true 319 | resolution: 320 | integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 321 | /mime/2.4.4: 322 | dev: false 323 | engines: 324 | node: '>=4.0.0' 325 | hasBin: true 326 | resolution: 327 | integrity: sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== 328 | /moment/2.21.0: 329 | dev: false 330 | resolution: 331 | integrity: sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ== 332 | /moment/2.24.0: 333 | dev: false 334 | resolution: 335 | integrity: sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== 336 | /ms/2.0.0: 337 | dev: false 338 | resolution: 339 | integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 340 | /ms/2.1.1: 341 | dev: false 342 | resolution: 343 | integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 344 | /ms/2.1.2: 345 | dev: false 346 | resolution: 347 | integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 348 | /negotiator/0.6.2: 349 | dev: false 350 | engines: 351 | node: '>= 0.6' 352 | resolution: 353 | integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== 354 | /netrc/0.1.4: 355 | dev: false 356 | resolution: 357 | integrity: sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ= 358 | /on-finished/2.3.0: 359 | dependencies: 360 | ee-first: 1.1.1 361 | dev: false 362 | engines: 363 | node: '>= 0.8' 364 | resolution: 365 | integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 366 | /parseurl/1.3.3: 367 | dev: false 368 | engines: 369 | node: '>= 0.8' 370 | resolution: 371 | integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 372 | /path-to-regexp/0.1.7: 373 | dev: false 374 | resolution: 375 | integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 376 | /proxy-addr/2.0.5: 377 | dependencies: 378 | forwarded: 0.1.2 379 | ipaddr.js: 1.9.0 380 | dev: false 381 | engines: 382 | node: '>= 0.10' 383 | resolution: 384 | integrity: sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== 385 | /qs/6.7.0: 386 | dev: false 387 | engines: 388 | node: '>=0.6' 389 | resolution: 390 | integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== 391 | /range-parser/1.2.1: 392 | dev: false 393 | engines: 394 | node: '>= 0.6' 395 | resolution: 396 | integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 397 | /raw-body/2.4.0: 398 | dependencies: 399 | bytes: 3.1.0 400 | http-errors: 1.7.2 401 | iconv-lite: 0.4.24 402 | unpipe: 1.0.0 403 | dev: false 404 | engines: 405 | node: '>= 0.8' 406 | resolution: 407 | integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== 408 | /safe-buffer/5.1.2: 409 | dev: false 410 | resolution: 411 | integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 412 | /safer-buffer/2.1.2: 413 | dev: false 414 | resolution: 415 | integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 416 | /send/0.17.1: 417 | dependencies: 418 | debug: 2.6.9 419 | depd: 1.1.2 420 | destroy: 1.0.4 421 | encodeurl: 1.0.2 422 | escape-html: 1.0.3 423 | etag: 1.8.1 424 | fresh: 0.5.2 425 | http-errors: 1.7.3 426 | mime: 1.6.0 427 | ms: 2.1.1 428 | on-finished: 2.3.0 429 | range-parser: 1.2.1 430 | statuses: 1.5.0 431 | dev: false 432 | engines: 433 | node: '>= 0.8.0' 434 | resolution: 435 | integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== 436 | /serve-static/1.14.1: 437 | dependencies: 438 | encodeurl: 1.0.2 439 | escape-html: 1.0.3 440 | parseurl: 1.3.3 441 | send: 0.17.1 442 | dev: false 443 | engines: 444 | node: '>= 0.8.0' 445 | resolution: 446 | integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== 447 | /setprototypeof/1.1.1: 448 | dev: false 449 | resolution: 450 | integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== 451 | /statuses/1.5.0: 452 | dev: false 453 | engines: 454 | node: '>= 0.6' 455 | resolution: 456 | integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 457 | /toidentifier/1.0.0: 458 | dev: false 459 | engines: 460 | node: '>=0.6' 461 | resolution: 462 | integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== 463 | /type-is/1.6.18: 464 | dependencies: 465 | media-typer: 0.3.0 466 | mime-types: 2.1.25 467 | dev: false 468 | engines: 469 | node: '>= 0.6' 470 | resolution: 471 | integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 472 | /unpipe/1.0.0: 473 | dev: false 474 | engines: 475 | node: '>= 0.8' 476 | resolution: 477 | integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 478 | /utils-merge/1.0.1: 479 | dev: false 480 | engines: 481 | node: '>= 0.4.0' 482 | resolution: 483 | integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 484 | /vary/1.1.2: 485 | dev: false 486 | engines: 487 | node: '>= 0.8' 488 | resolution: 489 | integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 490 | registry: 'https://registry.npmjs.org/' 491 | shrinkwrapMinorVersion: 9 492 | shrinkwrapVersion: 3 493 | specifiers: 494 | body-parser: ^1.18.2 495 | chrono-node: ^1.3.5 496 | express: ^4.15.3 497 | github: ^12.0.2 498 | moment: ^2.24.0 499 | --------------------------------------------------------------------------------8 | 9 | {{ page.pr_title }} 10 | 11 |
12 | {{ page.content }} 13 |
14 | {{ page.date | date: "%m %d, %Y" }} 15 |16 |