Skip to content

Add serverless backend #30

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
135 changes: 135 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,138 @@ cypress/videos/
cypress/screenshots/
cypress/downloads/
cypress.env.json

# Twilio Serverless
.twiliodeployinfo

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
.env.*

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ _Twilio Webchat React App_ is an application that demonstrates a website chat wi
2. [Features](#Features)
3. [Project structure](#Project-structure)
1. [React App](#1-react-app)
2. [Local backend server](#2-local-backend-server)
2. [Local backend with Express or Twilio Serverless](#2-local-backend
4. [Working in production](#working-in-production)
5. [Browser support](#Browser-support)
6. [Accessibility](#Accessibility)
Expand Down Expand Up @@ -65,8 +65,10 @@ You can find your **Conversations Service Sid** on the [services page](https://c
For the Address Sid, click on the edit button of your address and the edit screen will contain Address Sid. Note this Sid starts with `IG`.

## Working Locally
There are two ways to run locally, either with an Express server or Twilio Serverless functions
### 1. Start the Local Backend

### 1. Start the Local Backend Server
#### Option A - Express

```shell
yarn server
Expand All @@ -77,6 +79,17 @@ npm run server

Your server will be served at http://localhost:3001/.

#### Option B - Twilio Serverless

```shell
yarn serverless:build
yarn serverless:start

# or with npm
npm run serverless:build
npm run serverless:start
```

### 2. Start the Local React App Server

```shell
Expand Down Expand Up @@ -175,7 +188,8 @@ Additionally, the email-specific Cypress tests will be skipped if the emailing o
Twilio Webchat React App is an open source repository that includes:

1. A React App
2. A local backend server
2. A local backend (Express Server)
3. A local backend (Twilio Serverless)

## 1. React App

Expand Down Expand Up @@ -244,10 +258,11 @@ window.addEventListener("DOMContentLoaded", () => {
3. `transcript.emailSubject` configures what email customers receive in the email subject when they request an emailed transcript.
4. `transcript.emailContent` configures what email customers receive in the email body when they request an emailed transcript.

## 2. Local Backend Server
## 2. Local Backend

As mentioned before, Twilio Webchat App requires a backend to hit in order to work correctly.
This server — found in the `server` folder — exposes two main controllers.
An express server — found in the `server` folder — exposes two main controllers.
Alternatively a typescript Twilio Serverless implementation - found in the `serverless` folder - exposes the same controllers

### 1. InitWebchat

Expand Down
179 changes: 90 additions & 89 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,91 +1,92 @@
{
"name": "twilio-webchat-widget",
"version": "1.0.0",
"description": "",
"private": true,
"main": "src/index.tsx",
"license": "MIT",
"dependencies": {
"@emotion/core": "^10.0.28",
"@sendgrid/mail": "7.7.0",
"@twilio-paste/core": "^10.20.0",
"@twilio-paste/icons": "^6.1.0",
"@twilio-paste/theme": "^5.3.3",
"@twilio/conversations": "2.1.0-rc.0",
"@types/file-saver": "2.0.5",
"file-saver": "2.0.5",
"google-auth-library": "8.5.1",
"googleapis": "107.0.0",
"googleapis-common": "6.0.3",
"jszip": "3.10.1",
"lodash.merge": "^4.6.2",
"lodash.throttle": "^4.1.1",
"loglevel": "^1.7.1",
"mime-types": "^2.1.34",
"react": "^17.0.2",
"react-app-rewired": "^2.2.1",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-scripts": "^5.0.0",
"redux": "^4.1.2",
"redux-thunk": "^2.4.0",
"slugify": "1.6.5"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.15.1",
"@testing-library/react": "^12.1.2",
"@types/jest": "^27.0.3",
"@types/lodash.merge": "^4.6.6",
"@types/lodash.throttle": "^4.1.6",
"@types/mime-types": "^2.1.1",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"@typescript-eslint/eslint-plugin": "^5.3.1",
"@typescript-eslint/parser": "^5.4.0",
"axios": "^0.24.0",
"cors": "^2.8.5",
"cypress": "^9.3.1",
"cypress-file-upload": "^5.0.8",
"dotenv": "^16.0.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^7.2.0",
"eslint-config-twilio-react": "^1.35.1",
"eslint-config-twilio-ts": "^1.35.1",
"eslint-plugin-prettier": "^4.0.0",
"express": "4.17.2",
"fetch-mock-jest": "^1.5.1",
"jsonwebtoken": "^8.5.1",
"node-fetch": "^2.6.6",
"nodemon": "^2.0.15",
"prettier": "^2.4.1",
"twilio": "^3.74.0",
"typescript": "^4.4.2",
"webpack-bundle-analyzer": "^4.5.0"
},
"scripts": {
"start": "react-app-rewired start",
"server": "nodemon server",
"server:ci": "node server",
"build": "react-app-rewired build",
"test": "LC_ALL=\"en_GB.UTF-8\" react-app-rewired test --env=jsdom --transformIgnorePatterns \"node_modules/(?!(@twilio-paste|@twilio/conversations))/\"",
"test:nowatch": "yarn test --watchAll=false --verbose --runInBand",
"bootstrap": "node scripts/bootstrap",
"e2eCleanupExistingTasks": "node scripts/e2eCleanupExistingTasks",
"deploy": "yarn build && node scripts/deploy",
"eject": "react-app-rewired eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"jest": {
"setupFiles": [
"./jest.config.js"
]
},
"engines": {
"node": ">=14"
}
"name": "twilio-webchat-widget",
"version": "1.0.0",
"description": "",
"private": true,
"main": "src/index.tsx",
"license": "MIT",
"dependencies": {
"@emotion/core": "^10.0.28",
"@sendgrid/mail": "7.7.0",
"@twilio-paste/core": "^10.20.0",
"@twilio-paste/icons": "^6.1.0",
"@twilio-paste/theme": "^5.3.3",
"@twilio/conversations": "2.1.0-rc.0",
"@types/file-saver": "2.0.5",
"copyfiles": "^2.4.1",
"file-saver": "2.0.5",
"google-auth-library": "8.5.1",
"googleapis": "107.0.0",
"googleapis-common": "6.0.3",
"jszip": "3.10.1",
"lodash.merge": "^4.6.2",
"lodash.throttle": "^4.1.1",
"loglevel": "^1.7.1",
"mime-types": "^2.1.34",
"react": "^17.0.2",
"react-app-rewired": "^2.2.1",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-scripts": "^5.0.0",
"redux": "^4.1.2",
"redux-thunk": "^2.4.0",
"slugify": "1.6.5"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.15.1",
"@testing-library/react": "^12.1.2",
"@types/jest": "^27.0.3",
"@types/lodash.merge": "^4.6.6",
"@types/lodash.throttle": "^4.1.6",
"@types/mime-types": "^2.1.1",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"@typescript-eslint/eslint-plugin": "^5.3.1",
"@typescript-eslint/parser": "^5.4.0",
"axios": "^0.24.0",
"cors": "^2.8.5",
"cypress": "^9.3.1",
"cypress-file-upload": "^5.0.8",
"dotenv": "^16.0.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^7.2.0",
"eslint-config-twilio-react": "^1.35.1",
"eslint-config-twilio-ts": "^1.35.1",
"eslint-plugin-prettier": "^4.0.0",
"fetch-mock-jest": "^1.5.1",
"prettier": "^2.4.1",
"twilio": "^3.74.0",
"typescript": "^4.4.2",
"webpack-bundle-analyzer": "^4.5.0"
},
"scripts": {
"start": "react-app-rewired start",
"server": "nodemon server",
"server:ci": "node server",
"build": "react-app-rewired build",
"test": "LC_ALL=\"en_GB.UTF-8\" react-app-rewired test --env=jsdom --transformIgnorePatterns \"node_modules/(?!(@twilio-paste|@twilio/conversations))/\"",
"test:nowatch": "yarn test --watchAll=false --verbose --runInBand",
"bootstrap": "node scripts/bootstrap",
"e2eCleanupExistingTasks": "node scripts/e2eCleanupExistingTasks",
"deploy": "yarn build && npm run serverless:assets && npm run serverless:build",
"eject": "react-app-rewired eject",
"serverless:start": "cd serverless && twilio serverless start",
"serverless:build": "cd serverless && tsc",
"serverless:assets": "copyfiles -u 1 'build/**/*' serverless/assets && copyfiles build/index.html serverless/assets/assets",
"serverless:deploy": "npm run serverless:build && npm run serverless:assets && cd serverless && twilio serverless deploy"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"jest": {
"setupFiles": [
"./jest.config.js"
]
},
"engines": {
"node": ">=14"
}
}
Binary file added public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ app.listen(port, () => {
console.log(`Twilio Webchat App server running on port ${port}`);
});

app.post("/initWebchat", validateRequestOriginMiddleware, initWebchatController);
app.post("/refreshToken", validateRequestOriginMiddleware, refreshTokenController);
app.post("/api/initWebchat", validateRequestOriginMiddleware, initWebchatController);
app.post("/api/refreshToken", validateRequestOriginMiddleware, refreshTokenController);

app.post("/email", async (req, res) => {
try {
Expand Down
Loading