Skip to content

Commit

Permalink
Merge pull request #150 from JoinColony/feature/discord-webhooks
Browse files Browse the repository at this point in the history
Use discord webhook for contact form
  • Loading branch information
ceolson01 authored Jun 30, 2020
2 parents 3067519 + dbcae3b commit cbb1a18
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 103 deletions.
2 changes: 2 additions & 0 deletions .env.development.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# required
DOCS_GITHUB_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GHOST_CONTENT_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXX
DISCORD_WEBHOOK_ID_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
DISCORD_WEBHOOK_TOKEN_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# optional
COLONY_ADDRESS_MAINNET=0x84bc20B584fA28a278B7a8d5D1Ec5c71224c9f7C
Expand Down
2 changes: 2 additions & 0 deletions .env.production.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ GHOST_CONTENT_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_ANALYTICS_TRACKING_ID=XX-XXXXXXX-X
SERVER_URL=https://api.colony.io
SOCKET_URL=https://api.colony.io:8080
DISCORD_WEBHOOK_ID_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
DISCORD_WEBHOOK_TOKEN_CONTACT_FORM=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# optional
COLONY_ADDRESS_MAINNET=0x84bc20B584fA28a278B7a8d5D1Ec5c71224c9f7C
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* @flow */

export { default as useDiscordWebhook } from './useDiscordWebhook';
export { default as useElementHeight } from './useElementHeight';
export { default as useHubspotForm } from './useHubspotForm';
79 changes: 79 additions & 0 deletions src/hooks/useDiscordWebhook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* @flow */

import { useCallback, useState } from 'react';
// $FlowFixMe (definitions not updated for 1.3.x)
import { useLocation } from '@reach/router';

type WebhookConfig = {|
webhookId: string,
webhookToken: string,
|};

type Status = {| error: string |} | {| response: Object |} | void;

type OnError = () => void;
type OnSuccess = () => void;

type HookReturn = {|
error: ?string,
response: ?Object,
submitForm: (
formValues: Object,
onSuccess?: OnSuccess,
onError?: OnError,
) => Promise<void>,
|};

const useDiscordWebhook = ({
webhookId,
webhookToken,
}: WebhookConfig): HookReturn => {
const { pathname } = useLocation();
// @NOTE if this webhook starts getting spammed, we'll need to remove this feature
// eslint-disable-next-line max-len
const endpoint = `https://discordapp.com/api/webhooks/${webhookId}/${webhookToken}`;

const [status, setStatus] = useState<Status>();

const submitForm = useCallback(
async (formValues: Object, onSuccess?: OnSuccess, onError?: OnError) => {
// eslint-disable-next-line max-len
let content = `New submission via the website from \`${pathname}\`:\n\n`;
Object.keys(formValues).forEach(itemKey => {
content += `${itemKey}: ${formValues[itemKey]}\n`;
});
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json;',
},
body: JSON.stringify({
content,
}),
};

try {
// eslint-disable-next-line no-undef
await fetch(endpoint, fetchOptions);
setStatus({ response: 'Success!' });
if (onSuccess) {
onSuccess();
}
} catch (e) {
setStatus({ error: e.message });
if (onError) {
onError();
}
}
},
[endpoint, pathname],
);

return {
error: (status && status.error) || undefined,
response: (status && status.response) || undefined,
submitForm,
};
};

export default useDiscordWebhook;
145 changes: 60 additions & 85 deletions src/modules/pages/components/Website/Contact/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import Button from '~core/Button';
import Input from '~core/Input';
import Paragraph from '~core/Paragraph';
import Textarea from '~core/Textarea';
import { useHubspotForm } from '~hooks';
import { PAGE_CONTACT } from '~routes';
import { useDiscordWebhook } from '~hooks';

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

Expand All @@ -23,28 +22,28 @@ const MSG = defineMessages({
id: 'pages.Website.Contact.Form.labelUseCase',
defaultMessage: 'How do you plan to use Colony?',
},
placeholderCompanyName: {
id: 'pages.Website.Contact.Form.placeholderCompanyName',
placeholderProject: {
id: 'pages.Website.Contact.Form.placeholderProject',
defaultMessage: 'Company/Project name',
},
placeholderCompanySize: {
id: 'pages.Website.Contact.Form.placeholderCompanySize',
placeholderProjectSize: {
id: 'pages.Website.Contact.Form.placeholderProjectSize',
defaultMessage: 'Company/Project size',
},
placeholderEmail: {
id: 'pages.Website.Contact.Form.placeholderEmail',
defaultMessage: 'Email',
},
placeholderNameFirst: {
id: 'pages.Website.Contact.Form.placeholderNameFirst',
placeholderFirstName: {
id: 'pages.Website.Contact.Form.placeholderFirstName',
defaultMessage: 'First name',
},
placeholderNameLast: {
id: 'pages.Website.Contact.Form.placeholderNameLast',
placeholderLastName: {
id: 'pages.Website.Contact.Form.placeholderLastName',
defaultMessage: 'Last name',
},
placeholderWebsiteUrl: {
id: 'pages.Website.Contact.Form.placeholderWebsiteUrl',
placeholderWebsite: {
id: 'pages.Website.Contact.Form.placeholderWebsite',
defaultMessage: 'Website URL',
},
textError: {
Expand Down Expand Up @@ -74,65 +73,43 @@ type Props = {|
|};

const validationSchema = yup.object().shape({
companyName: yup.string().required(MSG.validationTextRequired),
companySize: yup.string().required(MSG.validationTextRequired),
project: yup.string().required(MSG.validationTextRequired),
projectSize: yup.string().required(MSG.validationTextRequired),
email: yup
.string()
.email(MSG.validationTextEmail)
.required(MSG.validationTextRequired),
nameFirst: yup.string().required(MSG.validationTextRequired),
nameLast: yup.string().required(MSG.validationTextRequired),
firstName: yup.string().required(MSG.validationTextRequired),
lastName: yup.string().required(MSG.validationTextRequired),
useCase: yup.string().required(MSG.validationTextRequired),
websiteUrl: yup.string().url(MSG.validationTextUrl),
website: yup.string().url(MSG.validationTextUrl),
});

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

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

const handleSubmit = useCallback(
(
{
companyName,
companySize,
email,
nameFirst,
nameLast,
useCase,
websiteUrl,
},
{ resetForm },
) => {
const formData = {
company: companyName,
company_size: companySize,
email,
how_do_you_plan_to_use_colony_: useCase,
firstname: nameFirst,
lastname: nameLast,
website: websiteUrl,
};
submitForm(formData, resetForm);
(values, { resetForm }) => {
submitForm(values, resetForm);
},
[submitForm],
);

return (
<Formik
initialValues={{
companyName: '',
companySize: '',
project: '',
projectSize: '',
email: '',
nameFirst: '',
nameLast: '',
firstName: '',
lastName: '',
useCase: '',
websiteUrl: '',
website: '',
...initialValues,
}}
onSubmit={handleSubmit}
Expand All @@ -144,13 +121,13 @@ const Form = ({ initialValues }: Props) => {
isValid,
touched,
values: {
companyName,
companySize,
project,
projectSize,
email,
nameFirst,
nameLast,
firstName,
lastName,
useCase,
websiteUrl,
website,
},
}) => {
const inputProps = {
Expand All @@ -174,70 +151,68 @@ const Form = ({ initialValues }: Props) => {
<Input
{...inputProps}
error={
errors.nameFirst && touched.nameFirst
? errors.nameFirst
errors.firstName && touched.firstName
? errors.firstName
: undefined
}
id={`${displayName}.nameFirst`}
name="nameFirst"
placeholder={MSG.placeholderNameFirst}
value={nameFirst}
id={`${displayName}.firstName`}
name="firstName"
placeholder={MSG.placeholderFirstName}
value={firstName}
/>
</div>
<div>
<Input
{...inputProps}
error={
errors.nameLast && touched.nameLast
? errors.nameLast
errors.lastName && touched.lastName
? errors.lastName
: undefined
}
id={`${displayName}.nameLast`}
name="nameLast"
placeholder={MSG.placeholderNameLast}
value={nameLast}
id={`${displayName}.lastName`}
name="lastName"
placeholder={MSG.placeholderLastName}
value={lastName}
/>
</div>
</div>
<Input
{...inputProps}
error={
errors.websiteUrl && touched.websiteUrl
? errors.websiteUrl
: undefined
errors.website && touched.website ? errors.website : undefined
}
id={`${displayName}.websiteUrl`}
name="websiteUrl"
placeholder={MSG.placeholderWebsiteUrl}
value={websiteUrl}
id={`${displayName}.website`}
name="website"
placeholder={MSG.placeholderWebsite}
value={website}
/>
<div className={styles.inline}>
<div>
<Input
{...inputProps}
error={
errors.companyName && touched.companyName
? errors.companyName
errors.project && touched.project
? errors.project
: undefined
}
id={`${displayName}.companyName`}
name="companyName"
placeholder={MSG.placeholderCompanyName}
value={companyName}
id={`${displayName}.project`}
name="project"
placeholder={MSG.placeholderProject}
value={project}
/>
</div>
<div>
<Input
{...inputProps}
error={
errors.companySize && touched.companySize
? errors.companySize
errors.projectSize && touched.projectSize
? errors.projectSize
: undefined
}
id={`${displayName}.companySize`}
name="companySize"
placeholder={MSG.placeholderCompanySize}
value={companySize}
id={`${displayName}.projectSize`}
name="projectSize"
placeholder={MSG.placeholderProjectSize}
value={projectSize}
/>
</div>
</div>
Expand Down
Loading

0 comments on commit cbb1a18

Please sign in to comment.