diff --git a/apps/api/src/campaign/campaign.service.spec.ts b/apps/api/src/campaign/campaign.service.spec.ts index 01633a49..c7969f9e 100644 --- a/apps/api/src/campaign/campaign.service.spec.ts +++ b/apps/api/src/campaign/campaign.service.spec.ts @@ -14,10 +14,11 @@ import { NotificationService } from '../sockets/notifications/notification.servi import { SendGridNotificationsProvider } from '../notifications/providers/notifications.sendgrid.provider' import { EmailService } from '../email/email.service' import { MarketingNotificationsService } from '../notifications/notifications.service' +import { SendGridParams } from '../notifications/providers/notifications.sendgrid.types' describe('CampaignService', () => { let service: CampaignService - let marketing: NotificationsProviderInterface + let marketing: NotificationsProviderInterface const mockCreateCampaign = { slug: 'test-slug', @@ -121,6 +122,14 @@ describe('CampaignService', () => { jest.spyOn(marketing, 'createNewContactList').mockImplementation(async () => 'list-id') jest.spyOn(marketing, 'updateContactList').mockImplementation(async () => '') + jest.spyOn(marketing, 'getContactLists').mockResolvedValue({ + statusCode: 200, + headers: '', + body: { + result: [], + _metadata: {}, + }, + }) jest.spyOn(service, 'createCampaignNotificationList') expect(await service.update(mockUpdateCampaign.id, updateData, mockCampaign)).toEqual( @@ -133,6 +142,7 @@ describe('CampaignService', () => { include: { campaignType: { select: { name: true, slug: true, category: true } } }, }) expect(service.createCampaignNotificationList).toHaveBeenCalledWith(updatedCampaign) + expect(marketing.createNewContactList).toHaveBeenCalledWith({ name: updatedCampaign.title, }) diff --git a/apps/api/src/campaign/campaign.service.ts b/apps/api/src/campaign/campaign.service.ts index d487e519..da8518a9 100644 --- a/apps/api/src/campaign/campaign.service.ts +++ b/apps/api/src/campaign/campaign.service.ts @@ -1037,9 +1037,17 @@ export class CampaignService { async createCampaignNotificationList(updated: { title: string; id: string }) { // Generate list in the marketing platform - const listId = await this.marketingNotificationsService.provider.createNewContactList({ - name: updated.title || updated.id, - }) + let listId: string + const lists = await this.marketingNotificationsService.provider.getContactLists() + const campaginEmailLists = lists.body.result + const exists = campaignEmailLists.find((campaign) => campaign.name === updated.title) + if (exists) { + listId = exists.id + } else { + listId = await this.marketingNotificationsService.provider.createNewContactList({ + name: updated.title || updated.id, + }) + } const name = updated.title || '' diff --git a/apps/api/src/notifications/providers/notifications.interface.providers.ts b/apps/api/src/notifications/providers/notifications.interface.providers.ts index 47d4e5a3..4e6e6d28 100644 --- a/apps/api/src/notifications/providers/notifications.interface.providers.ts +++ b/apps/api/src/notifications/providers/notifications.interface.providers.ts @@ -19,6 +19,7 @@ type NotificationsInterfaceParams = { RemoveFromUnsubscribedRes: unknown AddToUnsubscribedRes: unknown SendNotificationRes: unknown + contactListsRes: unknown } export abstract class NotificationsProviderInterface< @@ -35,4 +36,5 @@ export abstract class NotificationsProviderInterface< data: T['RemoveFromUnsubscribedParams'], ): Promise abstract sendNotification(data: T['SendNotificationParams']): Promise + abstract getContactLists(): Promise } diff --git a/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts b/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts index 6e0ee118..5778209c 100644 --- a/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts +++ b/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common' import { ConfigService } from '@nestjs/config' import sgClient from '@sendgrid/client' import { NotificationsProviderInterface } from './notifications.interface.providers' -import { SendGridParams } from './notifications.sendgrid.types' +import { ContactListRes, SGClientResponse, SendGridParams } from './notifications.sendgrid.types' import { ClientRequest } from '@sendgrid/client/src/request' import { DateTime } from 'luxon' @@ -25,6 +25,14 @@ export class SendGridNotificationsProvider } } + async getContactLists() { + const request = { + url: '/v3/marketing/lists', + method: 'GET', + } as ClientRequest + const [response] = await sgClient.request(request) + return response as SGClientResponse + } async createNewContactList(data: SendGridParams['CreateListParams']) { const request = { url: `/v3/marketing/lists`, diff --git a/apps/api/src/notifications/providers/notifications.sendgrid.types.ts b/apps/api/src/notifications/providers/notifications.sendgrid.types.ts index 8c907821..e178a7c5 100644 --- a/apps/api/src/notifications/providers/notifications.sendgrid.types.ts +++ b/apps/api/src/notifications/providers/notifications.sendgrid.types.ts @@ -1,4 +1,8 @@ +import { ClientResponse } from '@sendgrid/mail' import { MarketingTemplateHTMLFields } from '../marketing_templates/template.type' +import Response from '@sendgrid/helpers/classes/response' + +export type SGClientResponse = Response export type SendGridParams = { // Parameters @@ -22,6 +26,7 @@ export type SendGridParams = { RemoveFromUnsubscribedRes: unknown AddToUnsubscribedRes: unknown SendNotificationRes: unknown + contactListsRes: SGClientResponse // Implementation specific ContactData: ContactData @@ -81,3 +86,15 @@ type SendNotificationParams = { type GetContactsInfoRes = { [key: string]: { contact: { id: string; [key: string]: unknown; list_ids: string[] } } } + +type SendGridContactList = { + id: string + name: string + contact_count: number + _metadata: object +} + +export type ContactListRes = { + result: SendGridContactList[] + _metadata: object +}