feat: notifications (#172)

The Notifications API allows plugins to register Notification Providers which have `sendNotification` and `resendNotification`.

Each plugin can listen to any events transmittet over the event bus and the result of the notification send will be persisted in the database to allow for clear communications timeline + ability to resend notifications.
This commit is contained in:
Sebastian Rindom
2021-02-15 11:59:37 +01:00
committed by GitHub
parent 4229e241d0
commit 7308946e56
46 changed files with 1538 additions and 254 deletions
@@ -3,187 +3,26 @@ class OrderSubscriber {
totalsService,
orderService,
sendgridService,
eventBusService,
notificationService,
fulfillmentService,
}) {
this.orderService_ = orderService
this.totalsService_ = totalsService
this.sendgridService_ = sendgridService
this.eventBus_ = eventBusService
this.notificationService_ = notificationService
this.fulfillmentService_ = fulfillmentService
this.eventBus_.subscribe(
"order.shipment_created",
async ({ id, fulfillment_id }) => {
const order = await this.orderService_.retrieve(id, {
select: [
"shipping_total",
"discount_total",
"tax_total",
"refunded_total",
"gift_card_total",
"subtotal",
"total",
"refundable_amount",
],
relations: [
"customer",
"billing_address",
"shipping_address",
"discounts",
"shipping_methods",
"shipping_methods.shipping_option",
"payments",
"fulfillments",
"returns",
"gift_cards",
"gift_card_transactions",
"swaps",
"swaps.return_order",
"swaps.payment",
"swaps.shipping_methods",
"swaps.shipping_address",
"swaps.additional_items",
"swaps.fulfillments",
],
})
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id)
const data = {
...order,
tracking_number: shipment.tracking_numbers.join(", "),
}
await this.sendgridService_.transactionalEmail(
"order.shipment_created",
data
)
}
)
this.eventBus_.subscribe("order.gift_card_created", async (order) => {
await this.sendgridService_.transactionalEmail(
"order.gift_card_created",
order
)
})
this.eventBus_.subscribe("order.placed", async (orderObj) => {
try {
const order = await this.orderService_.retrieve(orderObj.id, {
select: [
"shipping_total",
"discount_total",
"tax_total",
"refunded_total",
"gift_card_total",
"subtotal",
"total",
],
relations: [
"customer",
"billing_address",
"shipping_address",
"discounts",
"shipping_methods",
"shipping_methods.shipping_option",
"payments",
"fulfillments",
"returns",
"gift_cards",
"gift_card_transactions",
"swaps",
"swaps.return_order",
"swaps.payment",
"swaps.shipping_methods",
"swaps.shipping_address",
"swaps.additional_items",
"swaps.fulfillments",
],
})
const {
subtotal,
tax_total,
discount_total,
shipping_total,
total,
} = order
const taxRate = order.tax_rate / 100
const currencyCode = order.currency_code.toUpperCase()
const items = order.items.map((i) => {
return {
...i,
price: `${((i.unit_price / 100) * (1 + taxRate)).toFixed(
2
)} ${currencyCode}`,
}
})
let discounts = []
if (order.discounts) {
discounts = order.discounts.map((discount) => {
return {
is_giftcard: false,
code: discount.code,
descriptor: `${discount.rule.value}${
discount.rule.type === "percentage" ? "%" : ` ${currencyCode}`
}`,
}
})
}
let giftCards = []
if (order.gift_cards) {
giftCards = order.gift_cards.map((gc) => {
return {
is_giftcard: true,
code: gc.code,
descriptor: `${gc.value} ${currencyCode}`,
}
})
discounts.concat(giftCards)
}
const data = {
...order,
date: order.created_at.toDateString(),
items,
discounts,
subtotal: `${((subtotal / 100) * (1 + taxRate)).toFixed(
2
)} ${currencyCode}`,
tax_total: `${(tax_total / 100).toFixed(2)} ${currencyCode}`,
discount_total: `${((discount_total / 100) * (1 + taxRate)).toFixed(
2
)} ${currencyCode}`,
shipping_total: `${((shipping_total / 100) * (1 + taxRate)).toFixed(
2
)} ${currencyCode}`,
total: `${(total / 100).toFixed(2)} ${currencyCode}`,
}
await this.sendgridService_.transactionalEmail("order.placed", data)
} catch (error) {
console.log(error)
}
})
this.eventBus_.subscribe("order.cancelled", async (order) => {
await this.sendgridService_.transactionalEmail("order.cancelled", order)
})
this.eventBus_.subscribe("order.completed", async (order) => {
await this.sendgridService_.transactionalEmail("order.completed", order)
})
this.eventBus_.subscribe("order.updated", async (order) => {
await this.sendgridService_.transactionalEmail("order.updated", order)
})
this.notificationService_.subscribe("order.shipment_created", "sendgrid")
this.notificationService_.subscribe("order.gift_card_created", "sendgrid")
this.notificationService_.subscribe("gift_card.created", "sendgrid")
this.notificationService_.subscribe("order.placed", "sendgrid")
this.notificationService_.subscribe("order.canceled", "sendgrid")
this.notificationService_.subscribe("customer.password_reset", "sendgrid")
this.notificationService_.subscribe("claim.shipment_created", "sendgrid")
this.notificationService_.subscribe("swap.shipment_created", "sendgrid")
this.notificationService_.subscribe("swap.created", "sendgrid")
this.notificationService_.subscribe("order.items_returned", "sendgrid")
this.notificationService_.subscribe("order.return_requested", "sendgrid")
}
}
@@ -10,13 +10,6 @@ class UserSubscriber {
data
)
})
this.eventBus_.subscribe("customer.password_reset", async (data) => {
await this.sendgridService_.transactionalEmail(
"customer.password_reset",
data
)
})
}
}