Skip to content

Commit b1ef088

Browse files
authored
Integrate Facebook Customer Chat (#331)
1 parent de9d49b commit b1ef088

22 files changed

Lines changed: 167 additions & 41 deletions

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ GOOGLE_CLIENT_SECRET=xxxxx
2727

2828
FACEBOOK_APP_ID=xxxxx
2929
FACEBOOK_APP_SECRET=xxxxx
30+
FACEBOOK_PAGE_ID=xxxxx
3031

3132
# PostgreSQL
3233
# https://www.postgresql.org/docs/current/static/libpq-envars.html

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
"not ie <= 11",
1313
"not op_mini all"
1414
],
15-
1615
"dependencies": {
1716
"@babel/polyfill": "^7.2.5",
1817
"@babel/runtime": "^7.3.1",
@@ -39,6 +38,7 @@
3938
"jsonwebtoken": "^8.5.0",
4039
"jwt-passport": "^0.0.5",
4140
"knex": "^0.16.3",
41+
"load-script": "^1.0.0",
4242
"lodash": "^4.17.11",
4343
"moment-timezone": "^0.5.23",
4444
"passport": "^0.4.0",

src/common/App.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,12 @@ class App extends React.PureComponent {
3636
state = { error: null };
3737

3838
componentDidRender = () => {
39-
const { history, title } = this.props;
39+
const { history, title, config } = this.props;
4040
window.document.title = title;
4141

42-
gtag('config', window.config.gaTrackingId, {
43-
page_title: title,
44-
page_location: window.location.href,
45-
page_path: `${window.location.pathname}${window.location.search}`,
46-
});
42+
// Track page views
43+
gtag('config', config.gaTrackingId, { transport_type: 'beacon' });
44+
// fb(FB => FB.AppEvents.logPageView());
4745

4846
const scrollY = getScrollPosition(history.location.key);
4947

src/common/CustomerChat.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* React Starter Kit for Firebase
3+
* https://github.com/kriasoft/react-firebase-starter
4+
* Copyright (c) 2015-present Kriasoft | MIT License
5+
*/
6+
7+
import React from 'react';
8+
import { fb } from '../utils';
9+
import { ConfigContext } from '../hooks';
10+
11+
// https://developers.facebook.com/docs/messenger-platform/discovery/customer-chat-plugin
12+
class CustomerChat extends React.PureComponent {
13+
componentDidMount() {
14+
this.timeout = setTimeout(() => {
15+
fb(FB => this.timeout && FB.XFBML.parse());
16+
}, 3000);
17+
}
18+
19+
componentWillUnmount() {
20+
clearTimeout(this.timeout);
21+
delete this.timeout;
22+
}
23+
24+
render() {
25+
return (
26+
<ConfigContext.Consumer>
27+
{config => (
28+
<div
29+
className="fb-customerchat"
30+
attribution="setup_tool"
31+
page_id={config.facebook.pageId}
32+
// theme_color="..."
33+
// logged_in_greeting="..."
34+
// logged_out_greeting="..."
35+
// greeting_dialog_display="..."
36+
// greeting_dialog_delay="..."
37+
// minimized="false"
38+
// ref="..."
39+
/>
40+
)}
41+
</ConfigContext.Consumer>
42+
);
43+
}
44+
}
45+
46+
export default CustomerChat;

src/common/LayoutToolbar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const styles = theme => ({
4545

4646
function LayoutToolbar({ classes: s, data: me, className, ...props }) {
4747
const [userMenuEl, setUserMenuEl] = useState(null);
48-
const { appName } = useConfig();
48+
const { app } = useConfig();
4949

5050
function openUserMenu(event) {
5151
setUserMenuEl(event.currentTarget);
@@ -60,7 +60,7 @@ function LayoutToolbar({ classes: s, data: me, className, ...props }) {
6060
<Toolbar>
6161
<Typography className={s.title} variant="h6" color="inherit">
6262
<Link className={s.link} href="/">
63-
{appName}
63+
{app.name}
6464
</Link>
6565
</Typography>
6666
<Button

src/hooks.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
/* @flow */
88

9-
import React from 'react';
9+
import React, { useContext, useEffect } from 'react';
1010
import { ReactRelayContext } from 'react-relay';
11+
import { fb } from './utils';
1112

1213
// Default history object (for unit tests)
1314
const history = { location: { pathname: '/' } };
@@ -17,17 +18,24 @@ export const HistoryContext = React.createContext(history);
1718
export const ResetContext = React.createContext(() => {});
1819

1920
export function useConfig() {
20-
return React.useContext(ConfigContext);
21+
return useContext(ConfigContext);
2122
}
2223

2324
export function useHistory() {
24-
return React.useContext(HistoryContext);
25+
return useContext(HistoryContext);
2526
}
2627

2728
export function useRelay() {
28-
return React.useContext(ReactRelayContext);
29+
return useContext(ReactRelayContext);
2930
}
3031

3132
export function useReset() {
32-
return React.useContext(ResetContext);
33+
return useContext(ResetContext);
34+
}
35+
36+
export function useFacebookEvent(event, callback, deps = []) {
37+
useEffect(() => {
38+
fb(FB => FB.Event.subscribe(event, callback), { async: false });
39+
return fb(FB => FB.Event.unsubscribe(event, callback), { async: false });
40+
}, deps);
3341
}

src/landing/HomeSponsors.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ function HomeSponsors({ classes: s }) {
4141
<div className={s.root}>
4242
{sponsors.map(x => (
4343
<a
44+
key={x.name}
4445
className={s.link}
4546
href={x.link}
4647
target="_blank"

src/landing/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default [
2323
import(/* webpackChunkName: 'home' */ './HomeHero'),
2424
],
2525
render: ([Home, HomeHero], data, { config }) => ({
26-
title: config.appName,
26+
title: config.app.name,
2727
component: (
2828
<Layout data={data} hero={<HomeHero />}>
2929
<Home data={data} />

src/legal/Privacy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const styles = theme => ({
1818
});
1919

2020
function Privacy({ classes: s }) {
21-
const { appOrigin } = useConfig();
21+
const { app } = useConfig();
2222
return (
2323
<div className={s.root}>
2424
<Typography variant="h3" gutterBottom>
@@ -27,8 +27,8 @@ function Privacy({ classes: s }) {
2727
<Typography paragraph>
2828
Your privacy is important to us. It is Company&#39;s policy to respect
2929
your privacy regarading any information we may collect from you across
30-
our website, <a href={appOrigin}>{appOrigin}</a>, and other sites we own
31-
and operate.
30+
our website, <a href={`${app.origin}/`}>{app.origin}</a>, and other
31+
sites we own and operate.
3232
</Typography>
3333
<Typography paragraph>
3434
We only ask for personal information when we truly need it to provide a

src/legal/Terms.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ const styles = theme => ({
2525
});
2626

2727
function Privacy({ classes: s }) {
28-
const { appOrigin } = useConfig();
28+
const { app } = useConfig();
2929
return (
3030
<div className={s.root}>
3131
<Typography variant="h3" gutterBottom>
3232
Terms of Use
3333
</Typography>
3434
<Typography variant="h5">1. Terms</Typography>
3535
<Typography paragraph>
36-
By accessing the website at <a href={appOrigin}>{appOrigin}</a>, you are
37-
agreeing to be bound by these terms of service, all applicable laws and
38-
regulations, and agree that you are responsible for compliance with any
39-
applicable local laws. If you do not agree with any of these terms, you
40-
are prohibited from using or accessing this site. The materials
41-
contained in this website are protected by applicable copyright and
42-
trademark law.
36+
By accessing the website at <a href={`${app.origin}/`}>{app.origin}</a>,
37+
you are agreeing to be bound by these terms of service, all applicable
38+
laws and regulations, and agree that you are responsible for compliance
39+
with any applicable local laws. If you do not agree with any of these
40+
terms, you are prohibited from using or accessing this site. The
41+
materials contained in this website are protected by applicable
42+
copyright and trademark law.
4343
</Typography>
4444
<Typography variant="h5">2. Use License</Typography>
4545
<ol className={s.list} type="a">

0 commit comments

Comments
 (0)