I'm currently developing a multi-tenant API with Strapi and for one of the parts I use the Strapi email designer plugin because I want to send some emails but I want them to be custom designed for each tenant, the problem is that the plugin's table is not accessible in the content manager of Strapi so I can only hard code the template to a specific endpoint, is there a way to have the plugin table in the content manager or for it to be referenced to a content manager table something like:
(table)tenant->(field)templateId => (ref-table)plugin-email-designer->(ref-field)templateId
you know so I can switch and set dynamically from the Strapi panel and not with hard-coded endpoints
I've checked your issue briefly, and there is option you are going to like, but it involves using patch-package
...
So, let's assume that you have strapi
project created and you have added strapi-plugin-email-designer
and you are using yarn v1.xx.xx
:
yarn add patch-package postinstall-postinstall
Go to node_modules/strapi-plugin-email-designer/server/content-types/email-template/schema.json
change following fileds:
{
...
"pluginOptions": {
"content-manager": {
"visible": true
},
"content-type-builder": {
"visible": true
}
},
...
}
now run
yarn patch-package strapi-plugin-email-designer
now open your projects package.json
and add to scripts:
{
"scripts": {
...
"postinstall": "patch-package"
}
}
run
yarn build
yarn develop
head to admin ui, you should see new Collection
:
Let's assume you added a relation has one
called email_template
to your model.
Next we need to add custom route, so in /src/api/tenant/routes/
create file called routes.js
/src/api/tenant/routes/routes.js
module.exports = {
routes: [
{
method: 'POST',
path: `/tenants/:id/send`,
handler: `tenant.send`
}
]
}
now, we need to add handler to controller:
/src/api/tenant/controllers/tenant.js
"use strict";
/**
* tenant controller
*/
const { createCoreController } = require("@strapi/strapi").factories;
module.exports = createCoreController("api::tenant.tenant", ({ strapi }) => ({
async send(ctx) {
const { id } = ctx.params;
const { data } = ctx.request.body;
// notice, if you need extra validation you add it here
// if (!data) return ctx.badRequest("no data was provided");
const { to, subject } = data;
const { email_template, ...tenant } = await strapi.db
.query("api::tenant.tenant")
// if you have extra relations it's better to populate them directly here
.findOne({ where: { id }, populate: ["email_template"] });
console.log(email_template);
try {
await strapi
.plugin("email-designer")
.service("email")
.sendTemplatedEmail(
{
to,
//from, < should be set in /config/plugins.js email.settings.defaultFrom
//replayTo < should be set in /config/plugins.js email.settings.defaultReplyTo
},
{
templateReferenceId: email_template.templateReferenceId,
subject,
},
{
...tenant,
// this equals to apply all the data you have in tenant
// this may need to be aligned between your tenant and template
}
);
return { success: `Message sent to ${to}` };
} catch (e) {
strapi.log.debug("📺: ", e);
return ctx.badRequest(null, e);
}
},
}));
don't forget to enable access to /api/tenants/:id/send
in admin panel, Settings - Roles
POST
http://localhost:1337/api/tenants/1/send
{
"data": {
"to" : "email@example.com",
"subject": "Hello World"
}
}
response:
{
"success": "Message sent to email@example.com"
}
pls note, there is no template validation, e.g. if you give it a wrong template it would not be happy