Umbriel is a simple mailing platform built with Node.js, TypeScript & Prisma.
diego3g / umbriel Goto Github PK
View Code? Open in Web Editor NEW✉️ Umbriel is a simple mailing platform built with Node.js, TypeScript & Prisma.
License: MIT License
✉️ Umbriel is a simple mailing platform built with Node.js, TypeScript & Prisma.
License: MIT License
Undo block
contact.
Update contact details as name and email.
Store the progress of the message sending inside the message stats.
This information maybe should not be calculated on every request.
Today, authenticated users can do anything inside Umbriel but it would be good if we could have some predefined roles with custom permissions.
Today if a user clicks twice it counts twice on metrics, it should count only one per user.
Get all senders and templates routes
Create a route that returns the amount of recipients based on a list of tag ids.
Every time a sender gets created or updated, we should send a validation email through AWS SES.
AWS SES do not allow any email to send messages, we need to validate them before start sending emails.
Make searchs case insensitive.
Let admins invite other members to Umbriel. The admin inputs the name and email, and the invited member receive an email with instructions to access.
We can use the RegisterUser
use case that is not being used today.
Allow the creation of segments.
Segments are group of tags.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
Datasource | Name | Replacement PR? |
---|---|---|
npm | @babel/plugin-proposal-class-properties |
|
npm | eslint-plugin-node |
|
npm | request |
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
supertest
, @types/supertest
)@types/jest
, jest
, ts-jest
)html-to-text
, @types/html-to-text
)uuid
, @types/uuid
)@prisma/client
, prisma
)These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@babel/cli
, @babel/core
, @babel/node
, @babel/plugin-proposal-class-properties
, @babel/preset-env
, @babel/preset-typescript
)@types/jest
, jest
)html-to-text
, @types/html-to-text
)@prisma/client
, prisma
)@typescript-eslint/eslint-plugin
, @typescript-eslint/parser
)docker-compose.yml
bitnami/zookeeper 3
bitnami/kafka 3
Dockerfile
.github/workflows/lint.yml
actions/checkout v2
actions/setup-node v2
bahmutov/npm-install v1
.github/workflows/porter_umbriel_api.yml
actions/checkout v2.3.5
.github/workflows/porter_umbriel_kafka.yml
actions/checkout v2.3.5
.github/workflows/porter_umbriel_queue.yml
actions/checkout v2.3.5
.github/workflows/porter_umbriel_sns_webhook.yml
actions/checkout v2.3.5
.github/workflows/test.yml
actions/checkout v2
bahmutov/npm-install v1
postgres 13
.github/workflows/tsc.yml
actions/checkout v2
actions/setup-node v2
bahmutov/npm-install v1
package.json
@prisma/client 3.0.2
aws-sdk 2.978.0
bcryptjs 2.4.3
bullmq 1.40.4
cors ^2.8.5
dotenv ^10.0.0
dotenv-flow ^3.2.0
express 4.17.1
html-to-text 8.0.0
inline-css ^3.0.0
ioredis 4.28.0
jsonwebtoken 8.5.1
kafkajs ^1.15.0
nodemailer 6.7.0
request ^2.88.2
sns-validator ^0.3.4
uuid 8.3.2
@babel/cli 7.14.8
@babel/core 7.15.0
@babel/node 7.14.9
@babel/plugin-proposal-class-properties 7.14.5
@babel/preset-env 7.15.0
@babel/preset-typescript 7.15.0
@types/bcryptjs 2.4.2
@types/cors 2.8.12
@types/dotenv-flow 3.2.0
@types/express 4.17.13
@types/html-to-text 8.0.1
@types/inline-css 3.0.1
@types/jest 27.0.1
@types/jsonwebtoken 8.5.5
@types/nodemailer 6.4.4
@types/request 2.48.7
@types/sns-validator 0.3.1
@types/supertest 2.0.11
@types/uuid 8.3.1
@typescript-eslint/eslint-plugin 4.33.0
@typescript-eslint/parser 4.33.0
babel-plugin-module-resolver 4.1.0
eslint 7.32.0
eslint-config-prettier 8.3.0
eslint-config-standard 16.0.3
eslint-plugin-import 2.24.2
eslint-plugin-import-helpers 1.1.0
eslint-plugin-node 11.1.0
eslint-plugin-prettier 4.0.0
eslint-plugin-promise 5.1.0
jest 27.3.1
pg 8.7.1
plop 2.7.4
prettier 2.4.1
prisma 3.0.2
supertest 6.1.6
ts-jest 27.0.7
ts-node-dev 1.1.8
tsconfig-paths 3.11.0
typescript 4.4.3
Allow contact to unsubscribe by clicking on the unsubscribe
link inside the email.
Create a dashboard with some metrics & graphs:
Allow to share the message content in a public URL.
Hey @gabriellopes00, I merged the PR #69 but I think that RequiredFieldsValidator
is not a good idea. I think we should add validation per field instead a validator that check for empty values within all request data. Can we fix that?
That's causing our tests to fail as userId
is present in the request due to the EnsureAuthenticatedMiddleware
but in the register route, this value is null so the tests are failing.
Today we only save the message content in HTML format when the user creates it, but this prevents us from updating that message before sending it as the HTML is not editable by DraftJS on front-end.
We should save the message content in Draft format until the message is sent.
When the message is sent, we should fill another column inside the messages table like finalBody
or finalContent
that will have the message final HTML so we don't lose track about the message content in Draft format.
Can the controller validations be made by creating a validator component within each module that requires a validation ? Example: Inside Account's modules, the RegisterUser controller needs a validator. Would be a good idea create a component called validator
with the rules to validate the email, the user name, to compare password and password_confirmation... inside account's module, and inject that dependency inside de controller. This way, inside the controller, just call this.validator.validate(email...)
. What do you think ?
All the search routes does not include a default order.
Today we are returning the ID from the relation between Tag and Contact and not the tag ID itself.
What happens when a bounce event is captured?
Allow user to send a message to a specific list of contacts by importing a CSV during the message creation. This action should not save any relation between that contacts to tags inside Umbriel.
After the email is sent, that list will not be reachable again, only the contacts individually that will be persisted to Umbriel database.
Wasn't the save supposed to update in prisma.user?
async save(user: User): Promise<void> {
const data = await UserMapper.toPersistence(user)
await prisma.message.update({
where: {
id: user.id,
},
data,
})
}
Delete contact and all its data.
The main point here is that it would not be good to lose track of that contact inside message stats, so I think the message stats should be stored instead of calculating it from recipients every time it's requested.
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
Undo unsubscribe
of the contact.
Today when we receive notifications of reads, clicks or opens from AWS SES we save all the event metadata on the database but we don't need the whole object, we need only some specific data like, on clicks we wan't to know which link was clicked.
Update sender data as name and email.
For now, we didn't implement a proper presentation layer with view models.
Maybe we could move the controllers to presentation layer if we want to leave the "package by feature" architecture.
For now, the template only received one variable: {{ message_content }}
, but it would be good to have other variables as:
{{ message_content }}
- The full content of a broadcast or sequence message
{{ address }}
- Your company's address, as set in your account settings
{{ unsubscribe_url }}
- Unsubscribe URL (use to customize the link text)
{{ subscriber_preferences_url }}
- Update Subscriber Preferences URL (use to customize the link text)
{{ subscriber.first_name }}
- The first name of the subscriber
{{ subscriber.email_address }}
- The email address of the subscriber
That's it (for now).
Let the user update the message ONLY if it's not sent yet.
Delete message templates.
I think we should not hard delete here, only store a deleted_at
on the database as the messages would probably using these templates and if we delete a template used by a message that as not sent yet, it'll lose track of it.
I sent an email for 18k contacts and noticed some CPU and memory problems.
When receiving some AWS events, the HTTP service was logging some errors with this trace:
PrismaClientKnownRequestError2 [PrismaClientKnownRequestError]: Unique constraint failed on the fields: (`message_id`,`contact_id`)
at cb (/home/node/app/node_modules/@prisma/client/runtime/index.js:34800:17)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async PrismaRecipientsRepository.saveWithEvents (/home/node/app/dist/modules/broadcasting/repositories/prisma/PrismaRecipientsRepository.js:41:5)
at async RegisterEvent.execute (/home/node/app/dist/modules/broadcasting/useCases/RegisterEvent/RegisterEvent.js:60:5)
at async RegisterEventController.handle (/home/node/app/dist/modules/broadcasting/useCases/RegisterEvent/RegisterEventController.js:90:22)
at async /home/node/app/dist/infra/http/adapters/ExpressRouteAdapter.js:15:26 {
code: 'P2002',
clientVersion: '2.28.0',
meta: { target: [ 'message_id', 'contact_id' ] }
}
Today there's not an option to select the mail or queue provider based on the configuration.
Crete a route that list all tags so we can use it during message creation.
Update message templates data as title and content.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.