✉️ Email-based intelligent virtual assistant (backend APIs)
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/classify
classifies text into actionsPOST /v1/api/parse-email
parses a raw email into structured dataPOST /v1/api/smart-tokenize
tokenizes text to actionable sentencesPOST /v1/api/perform-action
takes an email and processes itPOST /v1/api/read-receipt
saves a read receipt for an emailPOST /v1/api/meeting-page/:username/:id
returns public meeting detailsPOST /v1/api/confirm-meeting/:organizaionId/:meetingId
confirms a meetingPOST /v1/api/track/:index
tracks a usage eventCRUD 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
.
⚠️ FIX AVAILABLE: The fix for this is available in Prisma beta 5
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".logs
locations.data
meetings.proposedTimes
meetings.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
.
_staart
helpers/mail.ts
supports more parametersinit-tests.ts
has ===== lineThe 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:
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:
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.
PORT
is 7007
in development and 80
on productionBASE_URL
= https://api.myeiva.comFRONTEND_URL
= https://myeiva.comREDIS_URL
is redis://:KvEqnrLZJhGGEuNHNMcgG3sH@srv-captain--redis:6379
in production and not required for development if you have a local Redis instance running using redis-server
DATABASE_URL
= mysql://USER:PASSWORD@HOST:PORT/DATABASE
is set in .env
in the ./prisma
dirThis is used for both transactional emails (like password resets) using SES_EMAIL
and for sending emails from Ara (like meet-anand@mail.assistant.com
)
SES_EMAIL
is the email to send emails from (noreply@mail.myeiva.com
)SES_REGION
is the AWS region (us-east-1
)SES_ACCESS
is the AWS access key for SESSES_SECRET
is the AWS secret key for SESSTRIPE_SECRET_KEY
is the test key for development and live key for productionSTRIPE_PRODUCT_ID
is the product ID for Ara (prod_HAdEYq2FQrjVSd
for 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_1
CLEARBIT_SECRET_KEY_2
CLEARBIT_SECRET_KEY_3
…CLEARBIT_SECRET_KEY_10
(up to 10 API keys are supported)AWS_ELASTIC_ACCESS_KEY
is the AWS access key for ElasticSearchAWS_ELASTIC_SECRET_KEY
is the AWS secret key for ElasticSearchAWS_ELASTIC_HOST
is the AWS ElasticSearch endpointFor 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 3000
PM2 is used to run the app, and updating it is done using ./update.sh
.