Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(templates): add Opt In Builder template #261

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f4eabba
Initial commit
cweems May 4, 2021
a4390a0
Working dynamic values
cweems May 8, 2021
b1fefd7
Working variable save
cweems May 12, 2021
d3f6ba4
Working webhook integration
cweems May 26, 2021
2e06b06
Refactor to move functions to utils, add authentication
cweems May 27, 2021
236f510
Update Readme and make data tab pills update from settings
cweems Jun 10, 2021
bddf0a6
Save data source to backend
cweems Jun 10, 2021
036d0ba
Fix bug on TOS page
cweems Jun 10, 2021
a3a2b26
Update Readme
cweems Jun 10, 2021
d1e792f
Fix Segment and Airtable
cweems Jun 11, 2021
9d39e64
Add screenshot to readme
cweems Jun 14, 2021
a95bbd2
Fix json stringify issue in get-settings.js, layout html for cwarren …
cweems Jun 16, 2021
87beb12
Add more flexible message frequency editor
cweems Jun 17, 2021
195c53a
Merge pull request #3 from cweems/dev
cweems Jun 28, 2021
c8fe0a7
Add tests for get-settings
cweems Jun 29, 2021
3f01b81
Working save-settings test, removed baseUrl as unnecesasry
cweems Jul 16, 2021
8cfe35d
Working send-sms tests
cweems Jul 19, 2021
c60581b
Working back-end tests for compliance language warning
cweems Jul 20, 2021
309dd0b
Add compliance warning
cweems Jul 29, 2021
f883cd7
Rename tests and add comments to .env
cweems Jul 30, 2021
394fb6e
Add 'optin-builder/' from commit 'f883cd7dd18c028403b35edf76de15b467e…
cweems Jul 30, 2021
f61aefb
Change invalid prettier settings, lint public.js
cweems Jul 30, 2021
6e91e2c
Fully linted project with prettier/eslint passing
cweems Jul 30, 2021
b46d0fe
Fix get settings tests
cweems Jul 30, 2021
619ee76
Add dependencies to function-templates
cweems Jul 30, 2021
a58095c
Add .env file to optin-builder
cweems Jul 30, 2021
4d33998
Add additional packages to main function-templates package.json
cweems Jul 30, 2021
e2da4e2
Update tests with relative import
cweems Jul 30, 2021
15738ef
Change references to Twilio response in tests
cweems Aug 7, 2021
4ea6dd8
Add gitignore file
cweems Aug 7, 2021
1cdc4a1
Update templates.json with required information
cweems Aug 7, 2021
4c5aadf
Working receive-sms test
cweems Aug 10, 2021
423ae03
Merge branch 'main' into optin-builder
cweems Aug 10, 2021
07532cf
Expand tests on receive-sms
cweems Aug 10, 2021
e566dd3
Merge branch 'optin-builder' of github.com:cweems/function-templates …
cweems Aug 10, 2021
208014a
Fix base-url generation and simplify receive-sms function
cweems Aug 19, 2021
c285f5a
Fix merge conflict with main
cweems Aug 19, 2021
e585675
Remove .gitignore, .twilio-tunctions, .twiliodeployinfo
cweems Sep 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ module.exports = {
ecmaVersion: 2018,
},
rules: {
'prettier/prettier': 'allow',
'import/no-extraneous-dependencies': 'allow',
'prettier/prettier': 1,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was receiving errors from prettier saying that allow was deprecated, so I updated these configurations to match their new convention.

'import/no-extraneous-dependencies': 1,
'no-console': 0,
'sonarjs/no-duplicate-string': 'allow',
'sonarjs/no-identical-functions': 'allow',
'sonarjs/no-duplicate-string': 1,
'sonarjs/no-identical-functions': 1,
'func-names': 0,
'global-require': 0,
'no-shadow': 0,
'import/order': 'allow',
'import/order': 1,
'max-classes-per-file': 0,
},
};
94 changes: 94 additions & 0 deletions optin-builder/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# description: Your Twilio phone number for sending and receiving messages.
# format: phone_number
# required: true
TWILIO_PHONE_NUMBER=

# description: Set your phone number as the username for making edits to your app.
# format: secret
# required: true
ADMIN_PHONE_NUMBER=

# description: Set a password for your app. You'll use this later to change your opt-in settings.
# format: secret
# required: true
ADMIN_PASSWORD=

# description: Public URL to the organization's logo.
# configurable: false
LOGO_URL="/placeholder-icon.png"

# description: Title of the opt-in campaign.
# configurable: false
CAMPAIGN_TITLE=""

# description: Brief description of the opt-in campaign.
# configurable: false
CAMPAIGN_DESCRIPTION=""

# description: Statement of how often the subscriber will receive messages (e.g. 4 msgs / month.).
# configurable: false
MESSAGE_FREQUENCY=""

# description: Text on the registration button.
# configurable: false
BUTTON_CTA="Join"

# description: Keyword that users can text to opt-in to the campaign.
# configurable: false
OPT_IN_KEYWORD=

# description: Confirmation message sent to user once they have subscribed.
# configurable: false
SUBSCRIBE_CONFIRMATION=

# description: Contact information for Terms of Service.
# configurable: false
CONTACT_INFORMATION=""

# description: Public URL to a custom CSS file that will be loaded when the form renders.
# configurable: false
CUSTOM_CSS=

# description: Background color of the page.
# configurable: false
BACKGROUND_COLOR=

# description: Font color of the page.
# configurable: false
FONT_COLOR=

# description: Link to your organization's privacy policy.
# configurable: false
PRIVACY_POLICY_LINK=""

# description: Indicates which type of data storage will be used (Segment, Airtable, or Webhook).
# configurable: false
DATA_SOURCE=

# description: Segment write key.
# configurable: false
SEGMENT_WRITE_KEY=

# description: Airtable API key.
# configurable: false
AIRTABLE_API_KEY=

# description: Airtable Base ID.
# configurable: false
AIRTABLE_BASE_ID=

# description: Airtable table name.
# configurable: false
AIRTABLE_TABLE_NAME=

# description: Airtable phone number column name.
# configurable: false
AIRTABLE_PHONE_COLUMN_NAME=

# description: Airtable opt-in column name.
# configurable: false
AIRTABLE_OPT_IN_COLUMN_NAME=

# description: Webhook URL to send opt-in events to.
# configurable: false
WEBHOOK_URL=
1 change: 1 addition & 0 deletions optin-builder/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
86 changes: 86 additions & 0 deletions optin-builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Twilio Opt-In Builder

Easily create an embedable SMS Opt-In form to collect contacts for your campaign.

![Twilio Keyword Screenshot](https://user-images.githubusercontent.com/1418949/121948197-c944dd80-cd0b-11eb-8ce3-53a1405eb557.png)

## Key Features

* Live editor allows you to preview your signup form.
* Customizable logo, content, and colors.
* Generate compliance language and terms of service.
* Track opt-ins via webhook, Segment, or Airtable.
* Supports one-click keyword opt-in on Android and iOS.

## Pre-requisites

1. Install the [Twilio CLI](https://www.twilio.com/docs/twilio-cli/quickstart#install-twilio-cli)
2. Install the [serverless toolkit](https://www.twilio.com/docs/labs/serverless-toolkit/getting-started):

```shell
twilio plugins:install @twilio-labs/plugin-serverless
```
## Setup

3. Clone the repository and `cd` into it:
```shell
git clone [email protected]:cweems/twilio-keyword.git

cd twilio-keyword
```
4. Install dependencies:
```shell
npm install
```
5. Create `.env` file and set environment variables:
```shell
cp .env.example .env
```
> Note: you'll need to set `ACCOUNT_SID`, `AUTH_TOKEN`, `TWILIO_PHONE_NUMBER`, `ADMIN_PHONE_NUMBER`, and `ADMIN_PASSWORD` before deploying. All other environment variables can be set by the opt-in builder. If you're using Quick Deploy, these initial environemnt variables will be set for you.

6. Deploy to Twilio Serverless:
```shell
twilio serverless:deploy

# View your opt-in builder at https://[my-runtime-url].twil.io/index.html
```

7. Optional: develop locally if you want to edit HTML / CSS / JavaScript:
```shell
twilio serverless:start --live
```

### Environment Variable Reference
If you're running this project locally, you'll need to manually set environment variables in your `.env` file. When run on Twilio Serverless, environment variables are automatically set when you click the `Save Settings` button.

To keep your tokens and secrets secure, make sure to not commit the `.env` file in git. When setting up the project with `twilio serverless:init ...` the Twilio CLI will create a `.gitignore` file that excludes `.env` from the version history.

| Environment Variable | Description | Required? |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
| ACCOUNT_SID | Your Twilio Account SID | Required |
| AUTH_TOKEN | Your Twilio Account Auth Token | Required |
| TWILIO_PHONE_NUMBER | The phone number that you will send SMS opt-ins from. | Required |
| ADMIN_PHONE_NUMBER | Your personal phone number, we use this as a username when you save settings, and also to send you and SMS when your configuration changes. | Required |
| ADMIN_PASSWORD | Your password for updating settings via the live editor. | Required |
| LOGO_URL | A publicly accessible link to your organization's logo. | Recommended |
| CAMPAIGN_TITLE | The title of your opt-in page campaign. It should indicate what kinds of SMS your user is signing up for. | Required for compliance |
| CAMPAIGN_DESCRIPTION | A brief description of your opt-in campaign. What types of messages will the user receive? | Required for compliance |
| MESSAGE_FREQUENCY | The number of messages and cadence that a user will receive messages. | Required for compliance |
| BUTTON_CTA | The text on the button to register for the campaign. | Recommended |
| OPT_IN_KEYWORD | The keyword that the user must respond with for double opt-in. | Required for compliance |
| SUBSCRIBE_CONFIRMATION | The message that the user will receive once they have confirmed using double opt-in. | Required for compliance |
| CONTACT_INFORMATION | Your organization's contact information for compliance purposes (included in the Terms of Service). This could be a support email or toll-free number. | Required |
| CUSTOM_CSS | A link to a custom stylesheet. | Optional |
| BACKGROUND_COLOR | The background color for your signup page. | Optional |
| FONT_COLOR | The font color for your signup page. | Optional |
| PRIVACY_POLICY_LINK | A link to your organization's privacy policy. | Recommended required for compliance |
| DATA_SOURCE | The data storage destination for your opt-ins. Can be `webhook`, `airtable`, or `segment`. | Optional |
| SEGMENT_WRITE_KEY | The write key for your Segment Node.js source. Will be used to track opt-in events. | Optional |
| AIRTABLE_API_KEY | API key for your Airtable base if you are storing opt-ins in Airtable. | Optional |
| AIRTABLE_BASE_ID | Base ID for the Airtable base where you'll be storing opt-ins. | Optional |
| AIRTABLE_TABLE_NAME | Name of the table where you'll be storing your opt-ins. | Optional |
| AIRTABLE_PHONE_COLUMN_NAME | Name of the Airtable column where you'll store the phone numbers of your opt-ins. We'll check this column for existing opt-ins and remove the opt-in if the user responds with a stop word. | Optional |
| AIRTABLE_OPT_IN_COLUMN_NAME | Name of the column where you'll store opt-in status in Airtable. Values can be true / false. | Optional |
| WEBHOOK_URL | URL to a webhook on your own custom app that will receive Opt-In events. | Optional |


Loading