Skip to content

Commit cbb1a18

Browse files
authored
Merge pull request #150 from JoinColony/feature/discord-webhooks
Use discord webhook for contact form
2 parents 3067519 + dbcae3b commit cbb1a18

File tree

6 files changed

+166
-103
lines changed

6 files changed

+166
-103
lines changed

.env.development.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# required
22
DOCS_GITHUB_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
33
GHOST_CONTENT_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXX
4+
DISCORD_WEBHOOK_ID_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5+
DISCORD_WEBHOOK_TOKEN_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
46

57
# optional
68
COLONY_ADDRESS_MAINNET=0x84bc20B584fA28a278B7a8d5D1Ec5c71224c9f7C

.env.production.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ GHOST_CONTENT_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXX
44
GOOGLE_ANALYTICS_TRACKING_ID=XX-XXXXXXX-X
55
SERVER_URL=https://api.colony.io
66
SOCKET_URL=https://api.colony.io:8080
7+
DISCORD_WEBHOOK_ID_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8+
DISCORD_WEBHOOK_TOKEN_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
79

810
# optional
911
COLONY_ADDRESS_MAINNET=0x84bc20B584fA28a278B7a8d5D1Ec5c71224c9f7C

src/hooks/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* @flow */
22

3+
export { default as useDiscordWebhook } from './useDiscordWebhook';
34
export { default as useElementHeight } from './useElementHeight';
45
export { default as useHubspotForm } from './useHubspotForm';

src/hooks/useDiscordWebhook.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/* @flow */
2+
3+
import { useCallback, useState } from 'react';
4+
// $FlowFixMe (definitions not updated for 1.3.x)
5+
import { useLocation } from '@reach/router';
6+
7+
type WebhookConfig = {|
8+
webhookId: string,
9+
webhookToken: string,
10+
|};
11+
12+
type Status = {| error: string |} | {| response: Object |} | void;
13+
14+
type OnError = () => void;
15+
type OnSuccess = () => void;
16+
17+
type HookReturn = {|
18+
error: ?string,
19+
response: ?Object,
20+
submitForm: (
21+
formValues: Object,
22+
onSuccess?: OnSuccess,
23+
onError?: OnError,
24+
) => Promise<void>,
25+
|};
26+
27+
const useDiscordWebhook = ({
28+
webhookId,
29+
webhookToken,
30+
}: WebhookConfig): HookReturn => {
31+
const { pathname } = useLocation();
32+
// @NOTE if this webhook starts getting spammed, we'll need to remove this feature
33+
// eslint-disable-next-line max-len
34+
const endpoint = `https://discordapp.com/api/webhooks/${webhookId}/${webhookToken}`;
35+
36+
const [status, setStatus] = useState<Status>();
37+
38+
const submitForm = useCallback(
39+
async (formValues: Object, onSuccess?: OnSuccess, onError?: OnError) => {
40+
// eslint-disable-next-line max-len
41+
let content = `New submission via the website from \`${pathname}\`:\n\n`;
42+
Object.keys(formValues).forEach(itemKey => {
43+
content += `${itemKey}: ${formValues[itemKey]}\n`;
44+
});
45+
const fetchOptions = {
46+
method: 'POST',
47+
headers: {
48+
'Content-Type': 'application/json;',
49+
},
50+
body: JSON.stringify({
51+
content,
52+
}),
53+
};
54+
55+
try {
56+
// eslint-disable-next-line no-undef
57+
await fetch(endpoint, fetchOptions);
58+
setStatus({ response: 'Success!' });
59+
if (onSuccess) {
60+
onSuccess();
61+
}
62+
} catch (e) {
63+
setStatus({ error: e.message });
64+
if (onError) {
65+
onError();
66+
}
67+
}
68+
},
69+
[endpoint, pathname],
70+
);
71+
72+
return {
73+
error: (status && status.error) || undefined,
74+
response: (status && status.response) || undefined,
75+
submitForm,
76+
};
77+
};
78+
79+
export default useDiscordWebhook;

src/modules/pages/components/Website/Contact/Form.jsx

Lines changed: 60 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import Button from '~core/Button';
99
import Input from '~core/Input';
1010
import Paragraph from '~core/Paragraph';
1111
import Textarea from '~core/Textarea';
12-
import { useHubspotForm } from '~hooks';
13-
import { PAGE_CONTACT } from '~routes';
12+
import { useDiscordWebhook } from '~hooks';
1413

1514
import styles from './Form.module.css';
1615

@@ -23,28 +22,28 @@ const MSG = defineMessages({
2322
id: 'pages.Website.Contact.Form.labelUseCase',
2423
defaultMessage: 'How do you plan to use Colony?',
2524
},
26-
placeholderCompanyName: {
27-
id: 'pages.Website.Contact.Form.placeholderCompanyName',
25+
placeholderProject: {
26+
id: 'pages.Website.Contact.Form.placeholderProject',
2827
defaultMessage: 'Company/Project name',
2928
},
30-
placeholderCompanySize: {
31-
id: 'pages.Website.Contact.Form.placeholderCompanySize',
29+
placeholderProjectSize: {
30+
id: 'pages.Website.Contact.Form.placeholderProjectSize',
3231
defaultMessage: 'Company/Project size',
3332
},
3433
placeholderEmail: {
3534
id: 'pages.Website.Contact.Form.placeholderEmail',
3635
defaultMessage: 'Email',
3736
},
38-
placeholderNameFirst: {
39-
id: 'pages.Website.Contact.Form.placeholderNameFirst',
37+
placeholderFirstName: {
38+
id: 'pages.Website.Contact.Form.placeholderFirstName',
4039
defaultMessage: 'First name',
4140
},
42-
placeholderNameLast: {
43-
id: 'pages.Website.Contact.Form.placeholderNameLast',
41+
placeholderLastName: {
42+
id: 'pages.Website.Contact.Form.placeholderLastName',
4443
defaultMessage: 'Last name',
4544
},
46-
placeholderWebsiteUrl: {
47-
id: 'pages.Website.Contact.Form.placeholderWebsiteUrl',
45+
placeholderWebsite: {
46+
id: 'pages.Website.Contact.Form.placeholderWebsite',
4847
defaultMessage: 'Website URL',
4948
},
5049
textError: {
@@ -74,65 +73,43 @@ type Props = {|
7473
|};
7574

7675
const validationSchema = yup.object().shape({
77-
companyName: yup.string().required(MSG.validationTextRequired),
78-
companySize: yup.string().required(MSG.validationTextRequired),
76+
project: yup.string().required(MSG.validationTextRequired),
77+
projectSize: yup.string().required(MSG.validationTextRequired),
7978
email: yup
8079
.string()
8180
.email(MSG.validationTextEmail)
8281
.required(MSG.validationTextRequired),
83-
nameFirst: yup.string().required(MSG.validationTextRequired),
84-
nameLast: yup.string().required(MSG.validationTextRequired),
82+
firstName: yup.string().required(MSG.validationTextRequired),
83+
lastName: yup.string().required(MSG.validationTextRequired),
8584
useCase: yup.string().required(MSG.validationTextRequired),
86-
websiteUrl: yup.string().url(MSG.validationTextUrl),
85+
website: yup.string().url(MSG.validationTextUrl),
8786
});
8887

8988
const displayName = 'pages.Website.Contact.Form';
9089

9190
const Form = ({ initialValues }: Props) => {
92-
const { error, response, submitForm } = useHubspotForm({
93-
formGuid: '6bcced45-41e7-40eb-b3ec-42ac313eed0a',
94-
pageName: 'Contact',
95-
pageUri: `https://colony.io${PAGE_CONTACT}`,
96-
portalId: '4846129',
91+
const { error, response, submitForm } = useDiscordWebhook({
92+
webhookId: process.env.DISCORD_WEBHOOK_ID_CONTACT_FORM || '',
93+
webhookToken: process.env.DISCORD_WEBHOOK_TOKEN_CONTACT_FORM || '',
9794
});
9895

9996
const handleSubmit = useCallback(
100-
(
101-
{
102-
companyName,
103-
companySize,
104-
email,
105-
nameFirst,
106-
nameLast,
107-
useCase,
108-
websiteUrl,
109-
},
110-
{ resetForm },
111-
) => {
112-
const formData = {
113-
company: companyName,
114-
company_size: companySize,
115-
email,
116-
how_do_you_plan_to_use_colony_: useCase,
117-
firstname: nameFirst,
118-
lastname: nameLast,
119-
website: websiteUrl,
120-
};
121-
submitForm(formData, resetForm);
97+
(values, { resetForm }) => {
98+
submitForm(values, resetForm);
12299
},
123100
[submitForm],
124101
);
125102

126103
return (
127104
<Formik
128105
initialValues={{
129-
companyName: '',
130-
companySize: '',
106+
project: '',
107+
projectSize: '',
131108
email: '',
132-
nameFirst: '',
133-
nameLast: '',
109+
firstName: '',
110+
lastName: '',
134111
useCase: '',
135-
websiteUrl: '',
112+
website: '',
136113
...initialValues,
137114
}}
138115
onSubmit={handleSubmit}
@@ -144,13 +121,13 @@ const Form = ({ initialValues }: Props) => {
144121
isValid,
145122
touched,
146123
values: {
147-
companyName,
148-
companySize,
124+
project,
125+
projectSize,
149126
email,
150-
nameFirst,
151-
nameLast,
127+
firstName,
128+
lastName,
152129
useCase,
153-
websiteUrl,
130+
website,
154131
},
155132
}) => {
156133
const inputProps = {
@@ -174,70 +151,68 @@ const Form = ({ initialValues }: Props) => {
174151
<Input
175152
{...inputProps}
176153
error={
177-
errors.nameFirst && touched.nameFirst
178-
? errors.nameFirst
154+
errors.firstName && touched.firstName
155+
? errors.firstName
179156
: undefined
180157
}
181-
id={`${displayName}.nameFirst`}
182-
name="nameFirst"
183-
placeholder={MSG.placeholderNameFirst}
184-
value={nameFirst}
158+
id={`${displayName}.firstName`}
159+
name="firstName"
160+
placeholder={MSG.placeholderFirstName}
161+
value={firstName}
185162
/>
186163
</div>
187164
<div>
188165
<Input
189166
{...inputProps}
190167
error={
191-
errors.nameLast && touched.nameLast
192-
? errors.nameLast
168+
errors.lastName && touched.lastName
169+
? errors.lastName
193170
: undefined
194171
}
195-
id={`${displayName}.nameLast`}
196-
name="nameLast"
197-
placeholder={MSG.placeholderNameLast}
198-
value={nameLast}
172+
id={`${displayName}.lastName`}
173+
name="lastName"
174+
placeholder={MSG.placeholderLastName}
175+
value={lastName}
199176
/>
200177
</div>
201178
</div>
202179
<Input
203180
{...inputProps}
204181
error={
205-
errors.websiteUrl && touched.websiteUrl
206-
? errors.websiteUrl
207-
: undefined
182+
errors.website && touched.website ? errors.website : undefined
208183
}
209-
id={`${displayName}.websiteUrl`}
210-
name="websiteUrl"
211-
placeholder={MSG.placeholderWebsiteUrl}
212-
value={websiteUrl}
184+
id={`${displayName}.website`}
185+
name="website"
186+
placeholder={MSG.placeholderWebsite}
187+
value={website}
213188
/>
214189
<div className={styles.inline}>
215190
<div>
216191
<Input
217192
{...inputProps}
218193
error={
219-
errors.companyName && touched.companyName
220-
? errors.companyName
194+
errors.project && touched.project
195+
? errors.project
221196
: undefined
222197
}
223-
id={`${displayName}.companyName`}
224-
name="companyName"
225-
placeholder={MSG.placeholderCompanyName}
226-
value={companyName}
198+
id={`${displayName}.project`}
199+
name="project"
200+
placeholder={MSG.placeholderProject}
201+
value={project}
227202
/>
228203
</div>
229204
<div>
230205
<Input
231206
{...inputProps}
232207
error={
233-
errors.companySize && touched.companySize
234-
? errors.companySize
208+
errors.projectSize && touched.projectSize
209+
? errors.projectSize
235210
: undefined
236211
}
237-
id={`${displayName}.companySize`}
238-
name="companySize"
239-
placeholder={MSG.placeholderCompanySize}
240-
value={companySize}
212+
id={`${displayName}.projectSize`}
213+
name="projectSize"
214+
placeholder={MSG.placeholderProjectSize}
215+
value={projectSize}
241216
/>
242217
</div>
243218
</div>

0 commit comments

Comments
 (0)