fix callback not working in self-hosted version (#234)
This commit is contained in:
@@ -25,7 +25,7 @@ export class SesSettingsService {
|
|||||||
private static initialized = false;
|
private static initialized = false;
|
||||||
|
|
||||||
public static async getSetting(
|
public static async getSetting(
|
||||||
region = env.AWS_DEFAULT_REGION,
|
region = env.AWS_DEFAULT_REGION
|
||||||
): Promise<SesSetting | null> {
|
): Promise<SesSetting | null> {
|
||||||
await this.checkInitialized();
|
await this.checkInitialized();
|
||||||
|
|
||||||
@@ -75,13 +75,15 @@ export class SesSettingsService {
|
|||||||
|
|
||||||
if (!usesendUrlValidation.isValid) {
|
if (!usesendUrlValidation.isValid) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Callback URL: ${usesendUrl} is not valid, status: ${usesendUrlValidation.code} message:${usesendUrlValidation.error}`,
|
`Callback URL: ${usesendUrl} is not valid, status: ${usesendUrlValidation.code} message:${usesendUrlValidation.error}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const idPrefix = smallNanoid(10);
|
const idPrefix = smallNanoid(10);
|
||||||
let topicArn: string | undefined;
|
let topicArn: string | undefined;
|
||||||
|
|
||||||
|
let settingId: string | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const topicName = `${idPrefix}-${region}-unsend`;
|
const topicName = `${idPrefix}-${region}-unsend`;
|
||||||
topicArn = await sns.createTopic(topicName, region);
|
topicArn = await sns.createTopic(topicName, region);
|
||||||
@@ -89,28 +91,28 @@ export class SesSettingsService {
|
|||||||
throw new Error("Failed to create SNS topic");
|
throw new Error("Failed to create SNS topic");
|
||||||
}
|
}
|
||||||
|
|
||||||
const setting = await db.$transaction(async (tx) => {
|
const setting = await db.sesSetting.create({
|
||||||
const setting = await tx.sesSetting.create({
|
data: {
|
||||||
data: {
|
region,
|
||||||
region,
|
callbackUrl: `${parsedUrl}/api/ses_callback`,
|
||||||
callbackUrl: `${parsedUrl}/api/ses_callback`,
|
topic: topicName,
|
||||||
topic: topicName,
|
topicArn,
|
||||||
topicArn,
|
sesEmailRateLimit: sendingRateLimit,
|
||||||
sesEmailRateLimit: sendingRateLimit,
|
transactionalQuota,
|
||||||
transactionalQuota,
|
idPrefix,
|
||||||
idPrefix,
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await sns.subscribeEndpoint(
|
|
||||||
topicArn!,
|
|
||||||
`${setting.callbackUrl}`,
|
|
||||||
setting.region,
|
|
||||||
);
|
|
||||||
|
|
||||||
return setting;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
settingId = setting.id;
|
||||||
|
|
||||||
|
await this.invalidateCache();
|
||||||
|
|
||||||
|
await sns.subscribeEndpoint(
|
||||||
|
topicArn!,
|
||||||
|
`${setting.callbackUrl}`,
|
||||||
|
setting.region
|
||||||
|
);
|
||||||
|
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
throw new Error("Failed to create setting");
|
throw new Error("Failed to create setting");
|
||||||
}
|
}
|
||||||
@@ -120,14 +122,14 @@ export class SesSettingsService {
|
|||||||
EmailQueueService.initializeQueue(
|
EmailQueueService.initializeQueue(
|
||||||
region,
|
region,
|
||||||
setting.sesEmailRateLimit,
|
setting.sesEmailRateLimit,
|
||||||
setting.transactionalQuota,
|
setting.transactionalQuota
|
||||||
);
|
);
|
||||||
logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
transactionalQueue: EmailQueueService.transactionalQueue,
|
transactionalQueue: EmailQueueService.transactionalQueue,
|
||||||
marketingQueue: EmailQueueService.marketingQueue,
|
marketingQueue: EmailQueueService.marketingQueue,
|
||||||
},
|
},
|
||||||
"Email queues initialized",
|
"Email queues initialized"
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.invalidateCache();
|
await this.invalidateCache();
|
||||||
@@ -138,10 +140,18 @@ export class SesSettingsService {
|
|||||||
} catch (deleteError) {
|
} catch (deleteError) {
|
||||||
logger.error(
|
logger.error(
|
||||||
{ err: deleteError },
|
{ err: deleteError },
|
||||||
"Failed to delete SNS topic after error",
|
"Failed to delete SNS topic after error"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (settingId) {
|
||||||
|
await db.sesSetting.delete({
|
||||||
|
where: {
|
||||||
|
id: settingId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await this.invalidateCache();
|
||||||
logger.error({ err: error }, "Failed to create SES setting");
|
logger.error({ err: error }, "Failed to create SES setting");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -172,13 +182,13 @@ export class SesSettingsService {
|
|||||||
transactionalQueue: EmailQueueService.transactionalQueue,
|
transactionalQueue: EmailQueueService.transactionalQueue,
|
||||||
marketingQueue: EmailQueueService.marketingQueue,
|
marketingQueue: EmailQueueService.marketingQueue,
|
||||||
},
|
},
|
||||||
"Email queues before update",
|
"Email queues before update"
|
||||||
);
|
);
|
||||||
|
|
||||||
EmailQueueService.initializeQueue(
|
EmailQueueService.initializeQueue(
|
||||||
setting.region,
|
setting.region,
|
||||||
setting.sesEmailRateLimit,
|
setting.sesEmailRateLimit,
|
||||||
setting.transactionalQuota,
|
setting.transactionalQuota
|
||||||
);
|
);
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -186,7 +196,7 @@ export class SesSettingsService {
|
|||||||
transactionalQueue: EmailQueueService.transactionalQueue,
|
transactionalQueue: EmailQueueService.transactionalQueue,
|
||||||
marketingQueue: EmailQueueService.marketingQueue,
|
marketingQueue: EmailQueueService.marketingQueue,
|
||||||
},
|
},
|
||||||
"Email queues after update",
|
"Email queues after update"
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.invalidateCache();
|
await this.invalidateCache();
|
||||||
@@ -200,8 +210,9 @@ export class SesSettingsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async invalidateCache() {
|
static async invalidateCache() {
|
||||||
this.cache = {};
|
|
||||||
const settings = await db.sesSetting.findMany();
|
const settings = await db.sesSetting.findMany();
|
||||||
|
this.cache = {};
|
||||||
|
this.topicArns = [];
|
||||||
settings.forEach((setting) => {
|
settings.forEach((setting) => {
|
||||||
this.cache[setting.region] = setting;
|
this.cache[setting.region] = setting;
|
||||||
if (setting.topicArn) {
|
if (setting.topicArn) {
|
||||||
@@ -229,7 +240,7 @@ async function registerConfigurationSet(setting: SesSetting) {
|
|||||||
configGeneral,
|
configGeneral,
|
||||||
setting.topicArn,
|
setting.topicArn,
|
||||||
GENERAL_EVENTS,
|
GENERAL_EVENTS,
|
||||||
setting.region,
|
setting.region
|
||||||
);
|
);
|
||||||
|
|
||||||
const configClick = `${setting.idPrefix}-${setting.region}-unsend-click`;
|
const configClick = `${setting.idPrefix}-${setting.region}-unsend-click`;
|
||||||
@@ -237,7 +248,7 @@ async function registerConfigurationSet(setting: SesSetting) {
|
|||||||
configClick,
|
configClick,
|
||||||
setting.topicArn,
|
setting.topicArn,
|
||||||
[...GENERAL_EVENTS, "CLICK"],
|
[...GENERAL_EVENTS, "CLICK"],
|
||||||
setting.region,
|
setting.region
|
||||||
);
|
);
|
||||||
|
|
||||||
const configOpen = `${setting.idPrefix}-${setting.region}-unsend-open`;
|
const configOpen = `${setting.idPrefix}-${setting.region}-unsend-open`;
|
||||||
@@ -245,7 +256,7 @@ async function registerConfigurationSet(setting: SesSetting) {
|
|||||||
configOpen,
|
configOpen,
|
||||||
setting.topicArn,
|
setting.topicArn,
|
||||||
[...GENERAL_EVENTS, "OPEN"],
|
[...GENERAL_EVENTS, "OPEN"],
|
||||||
setting.region,
|
setting.region
|
||||||
);
|
);
|
||||||
|
|
||||||
const configFull = `${setting.idPrefix}-${setting.region}-unsend-full`;
|
const configFull = `${setting.idPrefix}-${setting.region}-unsend-full`;
|
||||||
@@ -253,7 +264,7 @@ async function registerConfigurationSet(setting: SesSetting) {
|
|||||||
configFull,
|
configFull,
|
||||||
setting.topicArn,
|
setting.topicArn,
|
||||||
[...GENERAL_EVENTS, "CLICK", "OPEN"],
|
[...GENERAL_EVENTS, "CLICK", "OPEN"],
|
||||||
setting.region,
|
setting.region
|
||||||
);
|
);
|
||||||
|
|
||||||
return await db.sesSetting.update({
|
return await db.sesSetting.update({
|
||||||
|
Reference in New Issue
Block a user