Created
August 25, 2019 22:09
-
-
Save ryanhugh/f92052e9274bd6f683e57104d766a7c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 24ee85b742572bd0daff251fd2116b21059eee12 Mon Sep 17 00:00:00 2001 | |
From: Ryan Hughes <[email protected]> | |
Date: Thu, 24 Jan 2019 21:03:03 -0500 | |
Subject: [PATCH 1/4] done | |
--- | |
backend/database.js | 11 ++-- | |
backend/notifyer.js | 8 ++- | |
backend/server.js | 9 +++ | |
frontend/components/Home.js | 10 ++- | |
frontend/components/scout logo.png | Bin 0 -> 2823 bytes | |
frontend/components/scout logo.svg | 9 +++ | |
frontend/css/_Home.scss | 97 ++++++++++++++++++++++++++--- | |
10 files changed, 128 insertions(+), 16 deletions(-) | |
create mode 100644 frontend/components/scout logo.png | |
create mode 100644 frontend/components/scout logo.svg | |
diff --git a/backend/database.js b/backend/database.js | |
index 2608771f..00f05792 100644 | |
--- a/backend/database.js | |
+++ b/backend/database.js | |
@@ -13,9 +13,12 @@ import MockFirebaseRef from './MockFirebaseRef'; | |
// This makes testing easier, avoids using production quota in development, | |
// and allows many people to test this class functionality (and other features that depend on it, such as notifyer.js) without the firebase access tokens. | |
// It also keeps the ability to run the development server offline. | |
+const USE_FIREBASE = true//macros.PROD | |
+ | |
+ | |
class Database { | |
constructor() { | |
- if (macros.PROD) { | |
+ if (USE_FIREBASE) { | |
// Promise for loading the firebase DB | |
this.dbPromise = this.loadDatabase(); | |
} else { | |
@@ -154,7 +157,7 @@ class Database { | |
// Value can be any JS object. | |
// If it has sub-objects you can easily dive into them in the Firebase console. | |
async set(key, value) { | |
- if (macros.PROD) { | |
+ if (USE_FIREBASE) { | |
const db = await this.dbPromise; | |
return db.ref(key).set(value); | |
} | |
@@ -166,7 +169,7 @@ class Database { | |
// Get the value at this key. | |
// Key follows the same form in the set method | |
async get(key) { | |
- if (macros.PROD) { | |
+ if (USE_FIREBASE) { | |
const db = await this.dbPromise; | |
const value = await db.ref(key).once('value'); | |
return value.val(); | |
@@ -178,7 +181,7 @@ class Database { | |
// Returns the raw firebase ref for a key | |
// Use this if you need to read a value, check something about it, and then write to it. | |
async getRef(key) { | |
- if (macros.PROD) { | |
+ if (USE_FIREBASE) { | |
const db = await this.dbPromise; | |
return db.ref(key); | |
} | |
diff --git a/backend/notifyer.js b/backend/notifyer.js | |
index 05fdc46f..953cfaa4 100644 | |
--- a/backend/notifyer.js | |
+++ b/backend/notifyer.js | |
@@ -18,13 +18,17 @@ const request = new Request('notifyer', { | |
class Notifyer { | |
// Webhook to respond to Facebook messages. | |
async sendFBNotification(sender, text) { | |
- if (sender.length !== 16 || sender.includes(',')) { | |
+ if (sender.includes(',')) { | |
macros.warn('Invalid sender ID:', sender); | |
return { | |
error: 'true', | |
}; | |
} | |
+ if (sender.length !== 16) { | |
+ macros.warn("Sender id length != 15, but allowing", sender) | |
+ } | |
+ | |
// If you want to message yourself in dev mode too, just change this. | |
// This check is here so we don't accidentally message people with dev data. | |
if (!macros.PROD && sender !== '1397905100304615') { | |
@@ -63,6 +67,8 @@ class Notifyer { | |
try { | |
const response = await request.post(config); | |
+ console.log(JSON.stringify(response, null, 4)) | |
+ | |
if (response.body.message_id) { | |
macros.log('Sent a fb message to ', sender, text, response.body.message_id); | |
return { | |
diff --git a/backend/server.js b/backend/server.js | |
index a743ed86..e7eebaf6 100644 | |
--- a/backend/server.js | |
+++ b/backend/server.js | |
@@ -566,6 +566,15 @@ app.post('/webhook/', wrap(async (req, res) => { | |
for (let i = 0; i < messagingEvents.length; i++) { | |
const event = messagingEvents[i]; | |
const sender = event.sender.id; | |
+ | |
+ if (String(parseInt(sender)).lengtht != 16) { | |
+ macros.log('Got a sender that was not 16 long!', JSON.stringify(event)) | |
+ } | |
+ | |
+ while (sender.length < 16) { | |
+ sender = `0${sender}`; | |
+ } | |
+ | |
if (event.message && event.message.text) { | |
const text = event.message.text; | |
diff --git a/frontend/components/Home.js b/frontend/components/Home.js | |
index 6ac0a58c..9d1fca52 100644 | |
--- a/frontend/components/Home.js | |
+++ b/frontend/components/Home.js | |
@@ -19,6 +19,7 @@ import macros from './macros'; | |
import ResultsLoader from './ResultsLoader'; | |
import EmailInput from './EmailInput'; | |
import logo from './logo.svg'; | |
+import scoutLogo from './scout logo.png'; | |
import boston from './boston.svg'; | |
// Terms that used to be scraped at one point, but are no longer scraped. | |
@@ -560,7 +561,14 @@ class Home extends React.Component { | |
{/* eslint-enable max-len */} | |
</a> | |
- <img src={ logo } className='logo' alt='logo' onClick={ this.onLogoClick } /> | |
+ <div className='logos' onClick={ this.onLogoClick }> | |
+ <img src={ logo } className='searchneuLogo' alt='logo'/> | |
+ <div className="scoutLogoContainer"> | |
+ <div className="scoutLogoPrefixText"> A </div> | |
+ <img src={ scoutLogo } className='scoutLogoImage' alt='logo'/> | |
+ <div className="scoutLogoPostText"> project</div> | |
+ </div> | |
+ </div> | |
<div className='bostonContainer' style={ bostonContainerStyle }> | |
<img src={ boston } className='boston' alt='logo' /> | |
diff --git a/frontend/components/scout logo.png b/frontend/components/scout logo.png | |
new file mode 100644 | |
index 0000000000000000000000000000000000000000..e22a24c3a0d5ffcf8251c1ff0b7cf1859f91abdb | |
GIT binary patch | |
literal 2823 | |
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 | |
Z0RXV*T^1wgNjCrh002ovPDHLkV1k|{tvmn# | |
literal 0 | |
HcmV?d00001 | |
diff --git a/frontend/components/scout logo.svg b/frontend/components/scout logo.svg | |
new file mode 100644 | |
index 00000000..00d063f3 | |
--- /dev/null | |
+++ b/frontend/components/scout logo.svg | |
@@ -0,0 +1,9 @@ | |
+<?xml version="1.0" encoding="utf-8"?> | |
+<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | |
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="35.252px" height="62.406px" viewBox="0 0 35.252 62.406" enable-background="new 0 0 35.252 62.406" xml:space="preserve"> | |
+ <path fill="#00A1B6" d="M35.252,16.05L25.989,0L0.076,14.961l7.829,23.487L0,46.354l9.268,16.052l25.909-14.962l-7.827-23.488 | |
+ L35.252,16.05z M24.707,4.784l6.171,10.689l-6.005,6.006L6.435,15.333L24.707,4.784z M4.956,18.531l17.148,5.716L10.673,35.681 | |
+ L4.956,18.531z M10.548,57.623L4.375,46.931l6.005-6.005l18.438,6.147L10.548,57.623z M30.296,43.874l-17.147-5.717L24.58,26.725 | |
+ L30.296,43.874z" /> | |
+</svg> | |
\ No newline at end of file | |
diff --git a/frontend/css/_Home.scss b/frontend/css/_Home.scss | |
index e77a32b5..11206473 100644 | |
--- a/frontend/css/_Home.scss | |
+++ b/frontend/css/_Home.scss | |
@@ -23,11 +23,6 @@ | |
pointer-events: none; | |
} | |
- .centerTextContainer { | |
- padding-bottom: 8%; | |
- } | |
- | |
- | |
.title { | |
color: rgb(174, 69, 67); | |
font-weight: 400; | |
@@ -42,13 +37,62 @@ | |
pointer-events: initial; | |
} | |
- .logo { | |
+ // .logo { | |
+ // position: absolute; | |
+ // height: 30px; | |
+ // top: 40px; | |
+ // left: 40px; | |
+ // z-index: 10; | |
+ // cursor: pointer; | |
+ // } | |
+ | |
+ .logos { | |
position: absolute; | |
- height: 30px; | |
- top: 40px; | |
- left: 40px; | |
+ top: 30px; | |
+ left: 30px; | |
z-index: 10; | |
cursor: pointer; | |
+ display: flex; | |
+ flex-direction: column; | |
+ } | |
+ | |
+ .searchneuLogo { | |
+ display: flex; | |
+ width: 200px; | |
+ } | |
+ | |
+ .scoutLogoContainer { | |
+ margin-top: 1px; | |
+ display: flex; | |
+ font-size: 18px; | |
+ margin-left: 27px; | |
+ } | |
+ | |
+ .scoutLogoPrefixText { | |
+ display: flex; | |
+ margin-right: 5px; | |
+ vertical-align: middle; | |
+ text-align: center; | |
+ display: flex; | |
+ justify-content: center; | |
+ flex-direction: column; | |
+ text-align: center; | |
+ color: #a3a3a3; | |
+ } | |
+ | |
+ .scoutLogoImage { | |
+ display: flex; | |
+ height: 34px; | |
+ } | |
+ | |
+ .scoutLogoPostText { | |
+ display: flex; | |
+ color: #a3a3a3; | |
+ display: flex; | |
+ justify-content: center; | |
+ flex-direction: column; | |
+ text-align: center; | |
+ margin-left: 2px; | |
} | |
.bostonContainer { | |
@@ -122,6 +166,10 @@ | |
transition-delay: 1s !important; | |
transition: opacity 1s; | |
} | |
+ | |
+ .centerTextContainer { | |
+ padding-bottom: 8%; | |
+ } | |
} | |
/* Mobile. */ | |
@@ -132,6 +180,34 @@ | |
margin-left: 10px !important; | |
max-width: none !important; | |
} | |
+ | |
+ .logos { | |
+ top: 17px; | |
+ left: 17px; | |
+ } | |
+ | |
+ .searchneuLogo { | |
+ width: 150px; | |
+ } | |
+ | |
+ .scoutLogoContainer { | |
+ font-size: 14px; | |
+ margin-left: 15px; | |
+ } | |
+ | |
+ .scoutLogoPrefixText { | |
+ margin-right: 5px; | |
+ } | |
+ | |
+ .scoutLogoImage { | |
+ height: 27px; | |
+ } | |
+ | |
+ .scoutLogoPostText { | |
+ margin-left: 2px; | |
+ } | |
+ | |
+ | |
} | |
/* Title and subtitle area. Desktop only. */ | |
@@ -168,6 +244,7 @@ | |
} | |
.title { | |
font-size: 45px; | |
+ line-height: 45px; | |
} | |
.subtitle { | |
@@ -339,7 +416,7 @@ | |
margin-left: auto; | |
margin-right: auto; | |
color: #888; | |
- margin-top: 62px; | |
+ margin-top: 24px; | |
line-height: 25px; | |
transition: opacity .6s; | |
transition-delay: 1s; | |
From ec91c0a0eb48d55d8fe345012b4c6e35ee50f1cf Mon Sep 17 00:00:00 2001 | |
From: Ryan Hughes <[email protected]> | |
Date: Fri, 25 Jan 2019 10:16:09 -0500 | |
Subject: [PATCH 2/4] Added a subtext for scout and search neu merger | |
--- | |
backend/database.js | 2 +- | |
backend/notifyer.js | 4 +- | |
backend/server.js | 2 +- | |
frontend/components/Home.js | 30 ++++++++++++--- | |
frontend/css/_Home.scss | 75 +++++++++++++++++++++++++++++++------ | |
5 files changed, 92 insertions(+), 21 deletions(-) | |
diff --git a/backend/database.js b/backend/database.js | |
index 00f05792..6f439c4c 100644 | |
--- a/backend/database.js | |
+++ b/backend/database.js | |
@@ -13,7 +13,7 @@ import MockFirebaseRef from './MockFirebaseRef'; | |
// This makes testing easier, avoids using production quota in development, | |
// and allows many people to test this class functionality (and other features that depend on it, such as notifyer.js) without the firebase access tokens. | |
// It also keeps the ability to run the development server offline. | |
-const USE_FIREBASE = true//macros.PROD | |
+const USE_FIREBASE = macros.PROD | |
class Database { | |
diff --git a/backend/notifyer.js b/backend/notifyer.js | |
index 953cfaa4..6e71a6e3 100644 | |
--- a/backend/notifyer.js | |
+++ b/backend/notifyer.js | |
@@ -26,7 +26,7 @@ class Notifyer { | |
} | |
if (sender.length !== 16) { | |
- macros.warn("Sender id length != 15, but allowing", sender) | |
+ macros.warn('Sender id length != 15, but allowing', sender); | |
} | |
// If you want to message yourself in dev mode too, just change this. | |
@@ -67,7 +67,7 @@ class Notifyer { | |
try { | |
const response = await request.post(config); | |
- console.log(JSON.stringify(response, null, 4)) | |
+ console.log(JSON.stringify(response, null, 4)); | |
if (response.body.message_id) { | |
macros.log('Sent a fb message to ', sender, text, response.body.message_id); | |
diff --git a/backend/server.js b/backend/server.js | |
index e7eebaf6..f438d956 100644 | |
--- a/backend/server.js | |
+++ b/backend/server.js | |
@@ -568,7 +568,7 @@ app.post('/webhook/', wrap(async (req, res) => { | |
const sender = event.sender.id; | |
if (String(parseInt(sender)).lengtht != 16) { | |
- macros.log('Got a sender that was not 16 long!', JSON.stringify(event)) | |
+ macros.log('Got a sender that was not 16 long!', JSON.stringify(event)); | |
} | |
while (sender.length < 16) { | |
diff --git a/frontend/components/Home.js b/frontend/components/Home.js | |
index 9d1fca52..7080f066 100644 | |
--- a/frontend/components/Home.js | |
+++ b/frontend/components/Home.js | |
@@ -545,6 +545,24 @@ class Home extends React.Component { | |
attentionSection = (<EmailInput containerStyle={ actionCenterStyle } />); | |
} | |
+ attentionSection = ( | |
+ <div style={ actionCenterStyle } className='searchneuScoutMergeConainer atentionContainer'> | |
+ <div className='mergerLogoContainers'> | |
+ <img className='mergerSearchNEULogo' src={ logo } alt='Search NEU Logo' /> | |
+ <div className='mergerPlusText'> + </div> | |
+ <img className='mergerScoutLogo' src={ scoutLogo } alt='Scout Logo' /> | |
+ </div> | |
+ <div className='mergerSubtext'> | |
+ Search NEU is now a part of Scout! <span role='img' aria-label='Rocket'>🚀</span> | |
+ </div> | |
+ <div | |
+ className='mergerSubSubText' | |
+ > | |
+ Read the blog post | |
+ </div> | |
+ </div> | |
+ ); | |
+ | |
// Not totally sure why, but this height: 100% removes the extra whitespace at the bottom of the page caused by the upward translate animation. | |
// Actually it only removes the extra whitespace on chrome. Need to come up with a better solution for other browsers. | |
@@ -561,12 +579,12 @@ class Home extends React.Component { | |
{/* eslint-enable max-len */} | |
</a> | |
- <div className='logos' onClick={ this.onLogoClick }> | |
- <img src={ logo } className='searchneuLogo' alt='logo'/> | |
- <div className="scoutLogoContainer"> | |
- <div className="scoutLogoPrefixText"> A </div> | |
- <img src={ scoutLogo } className='scoutLogoImage' alt='logo'/> | |
- <div className="scoutLogoPostText"> project</div> | |
+ <div className='logos' tabIndex={ 0 } role='button' onClick={ this.onLogoClick }> | |
+ <img src={ logo } className='searchneuLogo' alt='logo' /> | |
+ <div className='scoutLogoContainer'> | |
+ <div className='scoutLogoPrefixText'> A </div> | |
+ <img src={ scoutLogo } className='scoutLogoImage' alt='logo' /> | |
+ <div className='scoutLogoPostText'> project</div> | |
</div> | |
</div> | |
diff --git a/frontend/css/_Home.scss b/frontend/css/_Home.scss | |
index 11206473..2abe366b 100644 | |
--- a/frontend/css/_Home.scss | |
+++ b/frontend/css/_Home.scss | |
@@ -37,15 +37,6 @@ | |
pointer-events: initial; | |
} | |
- // .logo { | |
- // position: absolute; | |
- // height: 30px; | |
- // top: 40px; | |
- // left: 40px; | |
- // z-index: 10; | |
- // cursor: pointer; | |
- // } | |
- | |
.logos { | |
position: absolute; | |
top: 30px; | |
@@ -152,6 +143,58 @@ | |
outline: none; | |
} | |
+ .searchneuScoutMergeConainer { | |
+ display: flex; | |
+ flex-direction: column; | |
+ color: #a3a3a3; | |
+ // margin-top:50px; | |
+ font-weight: 200; | |
+ } | |
+ | |
+ .mergerLogoContainers { | |
+ display: flex; | |
+ flex-direction: row; | |
+ margin: 0 auto; | |
+ height: 75px; | |
+ } | |
+ | |
+ .mergerSearchNEULogo { | |
+ max-width: 32vw; | |
+ width: 160px; | |
+ margin-top: auto; | |
+ margin-bottom: auto; | |
+ } | |
+ | |
+ .mergerPlusText { | |
+ display: flex; | |
+ margin-top: auto; | |
+ margin-bottom: auto; | |
+ font-size: 30px; | |
+ margin-right: 7px; | |
+ margin-left: 7px; | |
+ } | |
+ | |
+ .mergerScoutLogo { | |
+ max-width: 32vw; | |
+ width: 160px; | |
+ margin: auto; | |
+ } | |
+ | |
+ .mergerSubtext { | |
+ font-size: 21px; | |
+ } | |
+ | |
+ .mergerSubSubText { | |
+ font-size: 20px; | |
+ margin-top: 2px; | |
+ } | |
+ | |
+ .mergerSubSubText:after { | |
+ overflow: hidden; | |
+ content: '\279C'; | |
+ padding-left: 3px; | |
+ } | |
+ | |
@@ -207,6 +250,16 @@ | |
margin-left: 2px; | |
} | |
+ .mergerSubtext { | |
+ font-size: 21px; | |
+ } | |
+ | |
+ .mergerSubtext { | |
+ font-size: 20px; | |
+ } | |
+ .mergerLogoContainers { | |
+ height: 50px; | |
+ } | |
} | |
@@ -416,7 +469,7 @@ | |
margin-left: auto; | |
margin-right: auto; | |
color: #888; | |
- margin-top: 24px; | |
+ margin-top: 50px; | |
line-height: 25px; | |
transition: opacity .6s; | |
transition-delay: 1s; | |
@@ -488,7 +541,7 @@ | |
} | |
-.home-container.mobileCompact .logo { | |
+.home-container.mobileCompact .logos { | |
display: none; | |
} | |
From 3604d9af7e0a87637ef296fcc4bc01f90cfc51a5 Mon Sep 17 00:00:00 2001 | |
From: Ryan Hughes <[email protected]> | |
Date: Sun, 25 Aug 2019 18:04:32 -0400 | |
Subject: [PATCH 3/4] Reverted some files | |
--- | |
backend/database.js | 34 ++++++------- | |
backend/notifyer.js | 29 ++++++----- | |
backend/server.js | 120 ++++++++++++++++++++++---------------------- | |
3 files changed, 88 insertions(+), 95 deletions(-) | |
diff --git a/backend/database.js b/backend/database.js | |
index 6f439c4c..a8d197f1 100644 | |
--- a/backend/database.js | |
+++ b/backend/database.js | |
@@ -13,22 +13,19 @@ import MockFirebaseRef from './MockFirebaseRef'; | |
// This makes testing easier, avoids using production quota in development, | |
// and allows many people to test this class functionality (and other features that depend on it, such as notifyer.js) without the firebase access tokens. | |
// It also keeps the ability to run the development server offline. | |
-const USE_FIREBASE = macros.PROD | |
- | |
- | |
class Database { | |
constructor() { | |
- if (USE_FIREBASE) { | |
- // Promise for loading the firebase DB | |
- this.dbPromise = this.loadDatabase(); | |
+ if (macros.PROD) { | |
+ // The firebase DB | |
+ this.db = this.loadDatabase(); | |
} else { | |
// In memory storage | |
this.memoryStorage = {}; | |
} | |
} | |
- async loadDatabase() { | |
- const firebaseConfig = await macros.getEnvVariable('firebaseConfig'); | |
+ loadDatabase() { | |
+ const firebaseConfig = macros.getEnvVariable('firebaseConfig'); | |
if (!firebaseConfig) { | |
macros.log('===================================================='); | |
macros.log("Don't have firebase config, probably going to crash."); | |
@@ -156,10 +153,9 @@ class Database { | |
// for users: /users/<user-id> (eg "/users/00000000000") | |
// Value can be any JS object. | |
// If it has sub-objects you can easily dive into them in the Firebase console. | |
- async set(key, value) { | |
- if (USE_FIREBASE) { | |
- const db = await this.dbPromise; | |
- return db.ref(key).set(value); | |
+ set(key, value) { | |
+ if (macros.PROD) { | |
+ return this.db.ref(key).set(value); | |
} | |
this.setMemoryStorage(this.standardizeKey(key), value); | |
@@ -169,10 +165,9 @@ class Database { | |
// Get the value at this key. | |
// Key follows the same form in the set method | |
async get(key) { | |
- if (USE_FIREBASE) { | |
- const db = await this.dbPromise; | |
- const value = await db.ref(key).once('value'); | |
- return value.val(); | |
+ if (macros.PROD) { | |
+ const value = this.db.ref(key).once('value'); | |
+ return (await value).val(); | |
} | |
return this.getMemoryStorage(this.standardizeKey(key)); | |
@@ -180,10 +175,9 @@ class Database { | |
// Returns the raw firebase ref for a key | |
// Use this if you need to read a value, check something about it, and then write to it. | |
- async getRef(key) { | |
- if (USE_FIREBASE) { | |
- const db = await this.dbPromise; | |
- return db.ref(key); | |
+ getRef(key) { | |
+ if (macros.PROD) { | |
+ return this.db.ref(key); | |
} | |
return new MockFirebaseRef(this, this.standardizeKey(key)); | |
diff --git a/backend/notifyer.js b/backend/notifyer.js | |
index 6e71a6e3..b2ff5843 100644 | |
--- a/backend/notifyer.js | |
+++ b/backend/notifyer.js | |
@@ -18,28 +18,25 @@ const request = new Request('notifyer', { | |
class Notifyer { | |
// Webhook to respond to Facebook messages. | |
async sendFBNotification(sender, text) { | |
- if (sender.includes(',')) { | |
- macros.warn('Invalid sender ID:', sender); | |
+ if (sender.length !== 16 || sender.includes(',')) { | |
+ macros.warn(`Invalid sender ID:"${sender}"`, sender.length, typeof sender); | |
return { | |
error: 'true', | |
}; | |
} | |
- if (sender.length !== 16) { | |
- macros.warn('Sender id length != 15, but allowing', sender); | |
- } | |
+ const devUserFbId = macros.getEnvVariable('fbMessengerId'); | |
// If you want to message yourself in dev mode too, just change this. | |
// This check is here so we don't accidentally message people with dev data. | |
- if (!macros.PROD && sender !== '1397905100304615') { | |
- macros.log('Refusing to send message to anyone other than Ryan not in prod mode'); | |
- macros.log('Not sending', sender, text); | |
+ if (!macros.PROD && sender !== devUserFbId) { | |
+ macros.log('Not sending fb message in dev mode ', text, sender, 'is not', devUserFbId, typeof text, typeof devUserFbId); | |
return { | |
error: 'true', | |
}; | |
} | |
- const token = await macros.getEnvVariable('fbToken'); | |
+ const token = macros.getEnvVariable('fbToken'); | |
if (!token) { | |
macros.warn("Don't have fbToken, not sending FB notification to", sender, text); | |
@@ -67,8 +64,6 @@ class Notifyer { | |
try { | |
const response = await request.post(config); | |
- console.log(JSON.stringify(response, null, 4)); | |
- | |
if (response.body.message_id) { | |
macros.log('Sent a fb message to ', sender, text, response.body.message_id); | |
return { | |
@@ -92,7 +87,7 @@ class Notifyer { | |
// Get some info about the user | |
// Docs here: https://developers.facebook.com/docs/messenger-platform/identity/user-profile | |
async getUserProfileInfo(sender) { | |
- const token = await macros.getEnvVariable('fbToken'); | |
+ const token = macros.getEnvVariable('fbToken'); | |
if (!token) { | |
macros.warn("Don't have fbToken, not getting user info for", sender); | |
@@ -110,8 +105,12 @@ class Notifyer { | |
return JSON.parse(response.body); | |
} | |
- main() { | |
- this.sendFBNotification('1397905100304615', 'test notification'); | |
+ | |
+ test() { | |
+ // currently on whatever your current id is | |
+ const devUserFbId = macros.getEnvVariable('fbMessengerId'); | |
+ | |
+ this.sendFBNotification(devUserFbId, 'test notification'); | |
} | |
} | |
@@ -119,5 +118,5 @@ const instance = new Notifyer(); | |
export default instance; | |
if (require.main === module) { | |
- instance.main(); | |
+ instance.test(); | |
} | |
diff --git a/backend/server.js b/backend/server.js | |
index 48039fe0..24d7ed7c 100644 | |
--- a/backend/server.js | |
+++ b/backend/server.js | |
@@ -21,42 +21,30 @@ import atob from 'atob'; | |
import _ from 'lodash'; | |
import Request from './scrapers/request'; | |
-import search from '../common/search'; | |
+import search from './search'; | |
import webpackConfig from './webpack.config.babel'; | |
import macros from './macros'; | |
import notifyer from './notifyer'; | |
import Updater from './updater'; | |
import database from './database'; | |
-import DataLib from '../common/classModels/DataLib'; | |
+import DataLib from './DataLib'; | |
+ | |
+// This file manages every endpoint in the backend | |
+// and calls out to respective files depending on what was called | |
const request = new Request('server'); | |
const app = express(); | |
-let xhubPromise; | |
-async function loadExpressHub() { | |
- if (xhubPromise) { | |
- return xhubPromise; | |
- } | |
- | |
- xhubPromise = macros.getEnvVariable('fbAppSecret').then((token) => { | |
- return xhub({ algorithm: 'sha1', secret: token }); | |
- }); | |
- | |
- return xhubPromise; | |
-} | |
-loadExpressHub(); | |
- | |
- | |
-// Start watching for new labs | |
-// psylink.startWatch(); | |
+// This xhub code is responsible for verifying that requests that hit the /webhook endpoint are from facebook in production | |
+// This does some crypto stuff to make this verification | |
+// This way, only facebook can make calls to the /webhook endpoint | |
+// This is not used in development | |
+const fbAppSecret = macros.getEnvVariable('fbAppSecret'); | |
// Verify that the webhooks are coming from facebook | |
// This needs to be above bodyParser for some reason | |
-app.use(wrap(async (req, res, next) => { | |
- const func = await xhubPromise; | |
- func(req, res, next); | |
-})); | |
+app.use(xhub({ algorithm: 'sha1', secret: fbAppSecret })); | |
// gzip the output | |
app.use(compress()); | |
@@ -150,6 +138,7 @@ function getRemoteIp(req) { | |
return splitHeader[splitHeader.length - 2].trim(); | |
} | |
+// Gets the current time, just used for loggin | |
function getTime() { | |
return moment().format('hh:mm:ss a'); | |
} | |
@@ -350,7 +339,13 @@ app.get('/search', wrap(async (req, res) => { | |
const startTime = Date.now(); | |
const searchOutput = index.search(req.query.query, req.query.termId, minIndex, maxIndex); | |
const midTime = Date.now(); | |
- const string = JSON.stringify(searchOutput.results); | |
+ | |
+ let string; | |
+ if (req.query.apiVersion === '2') { | |
+ string = JSON.stringify(searchOutput.resultsObject); | |
+ } else { | |
+ string = JSON.stringify(searchOutput.resultsObject.results); | |
+ } | |
const analytics = searchOutput.analytics; | |
@@ -368,8 +363,8 @@ app.get('/search', wrap(async (req, res) => { | |
// for Facebook verification of the endpoint. | |
-app.get('/webhook/', async (req, res) => { | |
- const verifyToken = await macros.getEnvVariable('fbVerifyToken'); | |
+app.get('/webhook/', (req, res) => { | |
+ const verifyToken = macros.getEnvVariable('fbVerifyToken'); | |
if (req.query['hub.verify_token'] === verifyToken) { | |
macros.log('yup!'); | |
@@ -566,15 +561,6 @@ app.post('/webhook/', wrap(async (req, res) => { | |
for (let i = 0; i < messagingEvents.length; i++) { | |
const event = messagingEvents[i]; | |
const sender = event.sender.id; | |
- | |
- if (String(parseInt(sender)).lengtht != 16) { | |
- macros.log('Got a sender that was not 16 long!', JSON.stringify(event)); | |
- } | |
- | |
- while (sender.length < 16) { | |
- sender = `0${sender}`; | |
- } | |
- | |
if (event.message && event.message.text) { | |
const text = event.message.text; | |
@@ -639,7 +625,7 @@ app.post('/subscribeEmail', wrap(async (req, res) => { | |
status: 'subscribed', | |
}; | |
- const mailChimpKey = await macros.getEnvVariable('mailChimpKey'); | |
+ const mailChimpKey = macros.getEnvVariable('mailChimpKey'); | |
if (mailChimpKey) { | |
if (macros.PROD) { | |
@@ -672,6 +658,7 @@ app.post('/subscribeEmail', wrap(async (req, res) => { | |
} | |
})); | |
+ | |
// Rate-limit submissions on a per-IP basis | |
let rateLimit = {}; | |
let lastHour = 0; | |
@@ -739,7 +726,7 @@ app.post('/submitFeedback', wrap(async (req, res) => { | |
} | |
})); | |
- | |
+// This variable is also used far below to serve static files from ram in dev | |
let middleware; | |
if (macros.DEV) { | |
@@ -757,6 +744,7 @@ if (macros.DEV) { | |
}, | |
}); | |
+ | |
app.use(middleware); | |
app.use(webpackHotMiddleware(compiler, { | |
log: false, | |
@@ -764,6 +752,21 @@ if (macros.DEV) { | |
} | |
+// Respond to requests for the api and log info to amplitude. | |
+app.get('/data/*', wrap(async (req, res, next) => { | |
+ // Gather some info and send it to amplitude | |
+ const info = { ...req.headers }; | |
+ | |
+ info.ip = getRemoteIp(req); | |
+ info.url = req.url; | |
+ | |
+ macros.logAmplitudeEvent('API Request', info); | |
+ | |
+ // Use express to send the static file | |
+ express.static('public')(req, res, next); | |
+})); | |
+ | |
+ | |
app.use(express.static('public')); | |
// Google Search Console Site Verification. | |
@@ -813,33 +816,30 @@ if (macros.DEV) { | |
} | |
-async function startServer() { | |
- const rollbarKey = await macros.getEnvVariable('rollbarPostServerItemToken'); | |
+const rollbarKey = macros.getEnvVariable('rollbarPostServerItemToken'); | |
- if (macros.PROD) { | |
- if (rollbarKey) { | |
- rollbar.init(rollbarKey); | |
- const rollbarFunc = rollbar.errorHandler(rollbarKey); | |
+if (macros.PROD) { | |
+ if (rollbarKey) { | |
+ rollbar.init(rollbarKey); | |
+ const rollbarFunc = rollbar.errorHandler(rollbarKey); | |
- // https://rollbar.com/docs/notifier/node_rollbar/ | |
- // Use the rollbar error handler to send exceptions to your rollbar account | |
- app.use(rollbarFunc); | |
- } else { | |
- macros.error("Don't have rollbar key! Skipping rollbar. :O"); | |
- } | |
- } else if (macros.DEV && !rollbarKey) { | |
- macros.log("Don't have rollbar key! Skipping rollbar. :O"); | |
+ // https://rollbar.com/docs/notifier/node_rollbar/ | |
+ // Use the rollbar error handler to send exceptions to your rollbar account | |
+ app.use(rollbarFunc); | |
+ } else { | |
+ macros.error("Don't have rollbar key! Skipping rollbar. :O"); | |
} | |
+} else if (macros.DEV && !rollbarKey) { | |
+ macros.log("Don't have rollbar key! Skipping rollbar. :O"); | |
+} | |
- app.listen(port, '0.0.0.0', (err) => { | |
- if (err) { | |
- macros.log(err); | |
- } | |
+app.listen(port, '0.0.0.0', (err) => { | |
+ if (err) { | |
+ macros.log(err); | |
+ } | |
- macros.logAmplitudeEvent('Backend Server startup', {}); | |
+ macros.logAmplitudeEvent('Backend Server startup', {}); | |
- macros.log(`Listening on port ${port}.`); | |
- }); | |
-} | |
-startServer(); | |
+ macros.log(`Listening on port ${port}.`); | |
+}); | |
From 34819666b774ae503cdbf480002a4186d1ba1457 Mon Sep 17 00:00:00 2001 | |
From: Ryan Hughes <[email protected]> | |
Date: Sun, 25 Aug 2019 18:05:29 -0400 | |
Subject: [PATCH 4/4] Reverted some files , v2 | |
--- | |
backend/database.js | 23 +++---- | |
backend/notifyer.js | 23 +++---- | |
backend/server.js | 143 +++++++++++++++++++++----------------------- | |
3 files changed, 89 insertions(+), 100 deletions(-) | |
diff --git a/backend/database.js b/backend/database.js | |
index a8d197f1..2608771f 100644 | |
--- a/backend/database.js | |
+++ b/backend/database.js | |
@@ -16,16 +16,16 @@ import MockFirebaseRef from './MockFirebaseRef'; | |
class Database { | |
constructor() { | |
if (macros.PROD) { | |
- // The firebase DB | |
- this.db = this.loadDatabase(); | |
+ // Promise for loading the firebase DB | |
+ this.dbPromise = this.loadDatabase(); | |
} else { | |
// In memory storage | |
this.memoryStorage = {}; | |
} | |
} | |
- loadDatabase() { | |
- const firebaseConfig = macros.getEnvVariable('firebaseConfig'); | |
+ async loadDatabase() { | |
+ const firebaseConfig = await macros.getEnvVariable('firebaseConfig'); | |
if (!firebaseConfig) { | |
macros.log('===================================================='); | |
macros.log("Don't have firebase config, probably going to crash."); | |
@@ -153,9 +153,10 @@ class Database { | |
// for users: /users/<user-id> (eg "/users/00000000000") | |
// Value can be any JS object. | |
// If it has sub-objects you can easily dive into them in the Firebase console. | |
- set(key, value) { | |
+ async set(key, value) { | |
if (macros.PROD) { | |
- return this.db.ref(key).set(value); | |
+ const db = await this.dbPromise; | |
+ return db.ref(key).set(value); | |
} | |
this.setMemoryStorage(this.standardizeKey(key), value); | |
@@ -166,8 +167,9 @@ class Database { | |
// Key follows the same form in the set method | |
async get(key) { | |
if (macros.PROD) { | |
- const value = this.db.ref(key).once('value'); | |
- return (await value).val(); | |
+ const db = await this.dbPromise; | |
+ const value = await db.ref(key).once('value'); | |
+ return value.val(); | |
} | |
return this.getMemoryStorage(this.standardizeKey(key)); | |
@@ -175,9 +177,10 @@ class Database { | |
// Returns the raw firebase ref for a key | |
// Use this if you need to read a value, check something about it, and then write to it. | |
- getRef(key) { | |
+ async getRef(key) { | |
if (macros.PROD) { | |
- return this.db.ref(key); | |
+ const db = await this.dbPromise; | |
+ return db.ref(key); | |
} | |
return new MockFirebaseRef(this, this.standardizeKey(key)); | |
diff --git a/backend/notifyer.js b/backend/notifyer.js | |
index b2ff5843..05fdc46f 100644 | |
--- a/backend/notifyer.js | |
+++ b/backend/notifyer.js | |
@@ -19,24 +19,23 @@ class Notifyer { | |
// Webhook to respond to Facebook messages. | |
async sendFBNotification(sender, text) { | |
if (sender.length !== 16 || sender.includes(',')) { | |
- macros.warn(`Invalid sender ID:"${sender}"`, sender.length, typeof sender); | |
+ macros.warn('Invalid sender ID:', sender); | |
return { | |
error: 'true', | |
}; | |
} | |
- const devUserFbId = macros.getEnvVariable('fbMessengerId'); | |
- | |
// If you want to message yourself in dev mode too, just change this. | |
// This check is here so we don't accidentally message people with dev data. | |
- if (!macros.PROD && sender !== devUserFbId) { | |
- macros.log('Not sending fb message in dev mode ', text, sender, 'is not', devUserFbId, typeof text, typeof devUserFbId); | |
+ if (!macros.PROD && sender !== '1397905100304615') { | |
+ macros.log('Refusing to send message to anyone other than Ryan not in prod mode'); | |
+ macros.log('Not sending', sender, text); | |
return { | |
error: 'true', | |
}; | |
} | |
- const token = macros.getEnvVariable('fbToken'); | |
+ const token = await macros.getEnvVariable('fbToken'); | |
if (!token) { | |
macros.warn("Don't have fbToken, not sending FB notification to", sender, text); | |
@@ -87,7 +86,7 @@ class Notifyer { | |
// Get some info about the user | |
// Docs here: https://developers.facebook.com/docs/messenger-platform/identity/user-profile | |
async getUserProfileInfo(sender) { | |
- const token = macros.getEnvVariable('fbToken'); | |
+ const token = await macros.getEnvVariable('fbToken'); | |
if (!token) { | |
macros.warn("Don't have fbToken, not getting user info for", sender); | |
@@ -105,12 +104,8 @@ class Notifyer { | |
return JSON.parse(response.body); | |
} | |
- | |
- test() { | |
- // currently on whatever your current id is | |
- const devUserFbId = macros.getEnvVariable('fbMessengerId'); | |
- | |
- this.sendFBNotification(devUserFbId, 'test notification'); | |
+ main() { | |
+ this.sendFBNotification('1397905100304615', 'test notification'); | |
} | |
} | |
@@ -118,5 +113,5 @@ const instance = new Notifyer(); | |
export default instance; | |
if (require.main === module) { | |
- instance.test(); | |
+ instance.main(); | |
} | |
diff --git a/backend/server.js b/backend/server.js | |
index 24d7ed7c..a743ed86 100644 | |
--- a/backend/server.js | |
+++ b/backend/server.js | |
@@ -21,30 +21,42 @@ import atob from 'atob'; | |
import _ from 'lodash'; | |
import Request from './scrapers/request'; | |
-import search from './search'; | |
+import search from '../common/search'; | |
import webpackConfig from './webpack.config.babel'; | |
import macros from './macros'; | |
import notifyer from './notifyer'; | |
import Updater from './updater'; | |
import database from './database'; | |
-import DataLib from './DataLib'; | |
- | |
-// This file manages every endpoint in the backend | |
-// and calls out to respective files depending on what was called | |
+import DataLib from '../common/classModels/DataLib'; | |
const request = new Request('server'); | |
const app = express(); | |
-// This xhub code is responsible for verifying that requests that hit the /webhook endpoint are from facebook in production | |
-// This does some crypto stuff to make this verification | |
-// This way, only facebook can make calls to the /webhook endpoint | |
-// This is not used in development | |
-const fbAppSecret = macros.getEnvVariable('fbAppSecret'); | |
+let xhubPromise; | |
+async function loadExpressHub() { | |
+ if (xhubPromise) { | |
+ return xhubPromise; | |
+ } | |
+ | |
+ xhubPromise = macros.getEnvVariable('fbAppSecret').then((token) => { | |
+ return xhub({ algorithm: 'sha1', secret: token }); | |
+ }); | |
+ | |
+ return xhubPromise; | |
+} | |
+loadExpressHub(); | |
+ | |
+ | |
+// Start watching for new labs | |
+// psylink.startWatch(); | |
// Verify that the webhooks are coming from facebook | |
// This needs to be above bodyParser for some reason | |
-app.use(xhub({ algorithm: 'sha1', secret: fbAppSecret })); | |
+app.use(wrap(async (req, res, next) => { | |
+ const func = await xhubPromise; | |
+ func(req, res, next); | |
+})); | |
// gzip the output | |
app.use(compress()); | |
@@ -138,7 +150,6 @@ function getRemoteIp(req) { | |
return splitHeader[splitHeader.length - 2].trim(); | |
} | |
-// Gets the current time, just used for loggin | |
function getTime() { | |
return moment().format('hh:mm:ss a'); | |
} | |
@@ -216,20 +227,20 @@ async function getFrontendData(file) { | |
async function loadPromises() { | |
- const termDumpPromise = getFrontendData('getTermDump/neu.edu/202010.json'); | |
- const searchIndexPromise = getFrontendData('getSearchIndex/neu.edu/202010.json'); | |
+ const termDumpPromise = getFrontendData('getTermDump/neu.edu/201910.json'); | |
+ const searchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201910.json'); | |
const spring2019DataPromise = getFrontendData('getTermDump/neu.edu/201930.json'); | |
const spring2019SearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201930.json'); | |
- const summer1DataPromise = getFrontendData('getTermDump/neu.edu/201940.json'); | |
- const summer1SearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201940.json'); | |
+ const summer1DataPromise = getFrontendData('getTermDump/neu.edu/201840.json'); | |
+ const summer1SearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201840.json'); | |
- const summer2DataPromise = getFrontendData('getTermDump/neu.edu/201960.json'); | |
- const summer2SearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201960.json'); | |
+ const summer2DataPromise = getFrontendData('getTermDump/neu.edu/201860.json'); | |
+ const summer2SearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201860.json'); | |
- const summerFullDataPromise = getFrontendData('getTermDump/neu.edu/201950.json'); | |
- const summerFullSearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201950.json'); | |
+ const summerFullDataPromise = getFrontendData('getTermDump/neu.edu/201850.json'); | |
+ const summerFullSearchIndexPromise = getFrontendData('getSearchIndex/neu.edu/201850.json'); | |
const employeeMapPromise = getFrontendData('employeeMap.json'); | |
const employeesSearchIndexPromise = getFrontendData('employeesSearchIndex.json'); | |
@@ -259,19 +270,19 @@ async function loadPromises() { | |
} | |
const dataLib = DataLib.loadData({ | |
- 202010: fallData, | |
+ 201910: fallData, | |
201930: springData, | |
- 201940: summer1Data, | |
- 201960: summer2Data, | |
- 201950: summerFullData, | |
+ 201840: summer1Data, | |
+ 201860: summer2Data, | |
+ 201850: summerFullData, | |
}); | |
const searchIndexies = { | |
- 202010: elasticlunr.Index.load(fallSearchIndex), | |
+ 201910: elasticlunr.Index.load(fallSearchIndex), | |
201930: elasticlunr.Index.load(springSearchIndex), | |
- 201940: elasticlunr.Index.load(summer1SearchIndex), | |
- 201960: elasticlunr.Index.load(summer2SearchIndex), | |
- 201950: elasticlunr.Index.load(summerFullSearchIndex), | |
+ 201840: elasticlunr.Index.load(summer1SearchIndex), | |
+ 201860: elasticlunr.Index.load(summer2SearchIndex), | |
+ 201850: elasticlunr.Index.load(summerFullSearchIndex), | |
}; | |
Updater.create(dataLib); | |
@@ -339,13 +350,7 @@ app.get('/search', wrap(async (req, res) => { | |
const startTime = Date.now(); | |
const searchOutput = index.search(req.query.query, req.query.termId, minIndex, maxIndex); | |
const midTime = Date.now(); | |
- | |
- let string; | |
- if (req.query.apiVersion === '2') { | |
- string = JSON.stringify(searchOutput.resultsObject); | |
- } else { | |
- string = JSON.stringify(searchOutput.resultsObject.results); | |
- } | |
+ const string = JSON.stringify(searchOutput.results); | |
const analytics = searchOutput.analytics; | |
@@ -363,8 +368,8 @@ app.get('/search', wrap(async (req, res) => { | |
// for Facebook verification of the endpoint. | |
-app.get('/webhook/', (req, res) => { | |
- const verifyToken = macros.getEnvVariable('fbVerifyToken'); | |
+app.get('/webhook/', async (req, res) => { | |
+ const verifyToken = await macros.getEnvVariable('fbVerifyToken'); | |
if (req.query['hub.verify_token'] === verifyToken) { | |
macros.log('yup!'); | |
@@ -625,7 +630,7 @@ app.post('/subscribeEmail', wrap(async (req, res) => { | |
status: 'subscribed', | |
}; | |
- const mailChimpKey = macros.getEnvVariable('mailChimpKey'); | |
+ const mailChimpKey = await macros.getEnvVariable('mailChimpKey'); | |
if (mailChimpKey) { | |
if (macros.PROD) { | |
@@ -658,7 +663,6 @@ app.post('/subscribeEmail', wrap(async (req, res) => { | |
} | |
})); | |
- | |
// Rate-limit submissions on a per-IP basis | |
let rateLimit = {}; | |
let lastHour = 0; | |
@@ -726,7 +730,7 @@ app.post('/submitFeedback', wrap(async (req, res) => { | |
} | |
})); | |
-// This variable is also used far below to serve static files from ram in dev | |
+ | |
let middleware; | |
if (macros.DEV) { | |
@@ -744,7 +748,6 @@ if (macros.DEV) { | |
}, | |
}); | |
- | |
app.use(middleware); | |
app.use(webpackHotMiddleware(compiler, { | |
log: false, | |
@@ -752,21 +755,6 @@ if (macros.DEV) { | |
} | |
-// Respond to requests for the api and log info to amplitude. | |
-app.get('/data/*', wrap(async (req, res, next) => { | |
- // Gather some info and send it to amplitude | |
- const info = { ...req.headers }; | |
- | |
- info.ip = getRemoteIp(req); | |
- info.url = req.url; | |
- | |
- macros.logAmplitudeEvent('API Request', info); | |
- | |
- // Use express to send the static file | |
- express.static('public')(req, res, next); | |
-})); | |
- | |
- | |
app.use(express.static('public')); | |
// Google Search Console Site Verification. | |
@@ -816,30 +804,33 @@ if (macros.DEV) { | |
} | |
-const rollbarKey = macros.getEnvVariable('rollbarPostServerItemToken'); | |
+async function startServer() { | |
+ const rollbarKey = await macros.getEnvVariable('rollbarPostServerItemToken'); | |
-if (macros.PROD) { | |
- if (rollbarKey) { | |
- rollbar.init(rollbarKey); | |
- const rollbarFunc = rollbar.errorHandler(rollbarKey); | |
+ if (macros.PROD) { | |
+ if (rollbarKey) { | |
+ rollbar.init(rollbarKey); | |
+ const rollbarFunc = rollbar.errorHandler(rollbarKey); | |
- // https://rollbar.com/docs/notifier/node_rollbar/ | |
- // Use the rollbar error handler to send exceptions to your rollbar account | |
- app.use(rollbarFunc); | |
- } else { | |
- macros.error("Don't have rollbar key! Skipping rollbar. :O"); | |
+ // https://rollbar.com/docs/notifier/node_rollbar/ | |
+ // Use the rollbar error handler to send exceptions to your rollbar account | |
+ app.use(rollbarFunc); | |
+ } else { | |
+ macros.error("Don't have rollbar key! Skipping rollbar. :O"); | |
+ } | |
+ } else if (macros.DEV && !rollbarKey) { | |
+ macros.log("Don't have rollbar key! Skipping rollbar. :O"); | |
} | |
-} else if (macros.DEV && !rollbarKey) { | |
- macros.log("Don't have rollbar key! Skipping rollbar. :O"); | |
-} | |
-app.listen(port, '0.0.0.0', (err) => { | |
- if (err) { | |
- macros.log(err); | |
- } | |
+ app.listen(port, '0.0.0.0', (err) => { | |
+ if (err) { | |
+ macros.log(err); | |
+ } | |
- macros.logAmplitudeEvent('Backend Server startup', {}); | |
+ macros.logAmplitudeEvent('Backend Server startup', {}); | |
- macros.log(`Listening on port ${port}.`); | |
-}); | |
+ macros.log(`Listening on port ${port}.`); | |
+ }); | |
+} | |
+startServer(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment