Ara is an AI-powered email communication assistant. This repo contains the backend APIs, based on staart/api.
Production API base URL: https://eiva-api.o15y.com
Apart from Staart API endpoints that let you create and manage accounts and billing, Ara also has some email communication-specific APIs that developers can use:
POST /v1/api/classifyclassifies text into actionsPOST /v1/api/parse-emailparses a raw email into structured dataPOST /v1/api/smart-tokenizetokenizes text to actionable sentencesPOST /v1/api/perform-actiontakes an email and processes itPOST /v1/api/read-receiptsaves a read receipt for an emailPOST /v1/api/meeting-page/:username/:idreturns public meeting detailsPOST /v1/api/confirm-meeting/:organizaionId/:meetingIdconfirms a meetingPOST /v1/api/track/:indextracks a usage event
CRUD endpoints:
/v1/organizations/:id/location/v1/organizations/:id/meetings
All API endpoints require an API key or access token; both can be generated using APIs or the webapp. Parameters are available in api/index.ts.
String in Prisma schema doesn't allow larger fields, so you have to manually convert the following fields to LONGTEXT from VARCHAR after generating tables. For details, see prisma/migrate#116
"incoming-emails".from"incoming-emails".to"incoming-emails".cc"incoming-emails".logslocations.datameetings.proposedTimesmeetings.guests
You might also have to make some of these changes after running npx prisma migrate up --experimental because it would overwrite the database schema.
Sometimes, the Prisma database hangs (blocks the main thread) during the initial tests. The trick is to make sure NODE_ENV = "development" is in env. I think this has something to do with line 7 of src/_staart/helpers/prisma.ts.
helpers/mail.tssupports more parametersinit-tests.tshas ===== line
The ara-assistant-incoming-emails bucket is used to store incoming emails to Ara as plain text files that can be fetched and parsed by this API. It's hosted in the eu-central-1 region and has limited, non-public access. An example of such an email is available in content/2mgh53qnuk650do2k3qlb5pv27obrl22uga8de01 and is called using /v1/api/webhooks/inbound/email/OBJECT_ID?secret=SECRET as explained below.
This serverless function EmailForwarder in invoked from AWS S3, when a new object is added to the emails bucket. The source code is available in content/mail-forwarder.js and is hosted in the eu-central-1 region with the Node.js 12.x runtime, 128 MB memory limit, and 1 minute execution timeout.
Key-value storage Redis is used for JWT cache invalidation and MySQL query caching. For production, a self-hosted Redis instance is used using Caprover, available only to other Caprover applications. For development, a local redis-server with default configuration will do.
A dedicated server is used for deploying the EIVA service. This uses AWS Lightsail which provides an easy-to-use interface for AWS EC2.
Instance details:
- Region: Frankfurt (eu-central-1)
- RAM: 4 GB
- Processor: 2 vCPUs
- Storage: 80 GB SSD
- Public IP address: 18.195.203.61
- Billing period: May 21, 2020–present
A dedicated ElasticSearch instance is used to store server logs, and more importantly track usage events using the /v1/api/track/:index API endpoint. This data will be used for analytics about pages, time on site, etc.
Instance details:
- Elasticsearch version: 7.4
- Instance type: r5.large.elasticsearch
- Number of nodes: 1
- Data nodes storage type: EBS
- EBS volume type: General Purpose (SSD)
- EBS volume size: 10 GiB
- Billing period: May 21, 2020–present
These environment variables (with the exception of DATABASE_URL) can be set in the .env file, or available as environment variables in the process using the Caprover UI or Dockerfile.
PORTis7007in development and80on productionBASE_URL= https://api.myeiva.comFRONTEND_URL= https://myeiva.comREDIS_URLisredis://:KvEqnrLZJhGGEuNHNMcgG3sH@srv-captain--redis:6379in production and not required for development if you have a local Redis instance running usingredis-serverDATABASE_URL=mysql://USER:PASSWORD@HOST:PORT/DATABASEis set in.envin the./prismadir
This is used for both transactional emails (like password resets) using SES_EMAIL and for sending emails from Ara (like [email protected])
SES_EMAILis the email to send emails from ([email protected])SES_REGIONis the AWS region (us-east-1)SES_ACCESSis the AWS access key for SESSES_SECRETis the AWS secret key for SES
STRIPE_SECRET_KEYis the test key for development and live key for productionSTRIPE_PRODUCT_IDis the product ID for Ara (prod_HAdEYq2FQrjVSdfor testing)
Clearbit is used to find information about guests, emails, and more. There are multiple API keys that are rotated. The secret API keys are stored in variables like:
CLEARBIT_SECRET_KEY_1CLEARBIT_SECRET_KEY_2CLEARBIT_SECRET_KEY_3...CLEARBIT_SECRET_KEY_10(up to 10 API keys are supported)
AWS_ELASTIC_ACCESS_KEYis the AWS access key for ElasticSearchAWS_ELASTIC_SECRET_KEYis the AWS secret key for ElasticSearchAWS_ELASTIC_HOSTis the AWS ElasticSearch endpoint
For incoming emails, the /v1/webhooks/inbound/email/OBJECT_ID?secret=SECRET URL is used. The following is a real example for the URL that will work locally:
http://localhost:7001/v1/webhooks/inbound/email/2mgh53qnuk650do2k3qlb5pv27obrl22uga8de01?secret=ebbb11de0c0400bf869bd48537ab56676715ec78173191ed377b0cae9a3eb6d0
To generate the secret, sign the object ID using HMAC with SHA-256 and the secret. The secret is stored as the environment variable INCOMING_EMAIL_WEBHOOK_SECRET as defined above. In Node.js, you can generate it using:
const { createHmac } = require("crypto");
createHmac("sha256", INCOMING_EMAIL_WEBHOOK_SECRET)
.update(objectId)
.digest("hex");The environment variable PORT is used to run the app on a specific port. In production, this is 3000.
The following command is used to redirect port 80 to 3000 (source):
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000PM2 is used to run the app, and updating it is done using ./update.sh.