From f5f1bf6daf79bb4eefdf6bb4cca4d9e555ef1a23 Mon Sep 17 00:00:00 2001 From: David Hochbaum Date: Tue, 10 Dec 2024 11:22:00 -0500 Subject: [PATCH] Individual emails for each segment --- ...auth.module.ts => listserv-auth.module.ts} | 2 +- ...th.service.ts => listserv-auth.service.ts} | 0 .../src/send-update/send-update.controller.ts | 101 +++++++++++++----- server/src/send-update/send-update.module.ts | 4 +- server/src/send-update/send-update.service.ts | 13 ++- 5 files changed, 85 insertions(+), 35 deletions(-) rename server/src/listserv/{auth.module.ts => listserv-auth.module.ts} (76%) rename server/src/listserv/{auth.service.ts => listserv-auth.service.ts} (100%) diff --git a/server/src/listserv/auth.module.ts b/server/src/listserv/listserv-auth.module.ts similarity index 76% rename from server/src/listserv/auth.module.ts rename to server/src/listserv/listserv-auth.module.ts index 9edfb4be..0ed03cc8 100644 --- a/server/src/listserv/auth.module.ts +++ b/server/src/listserv/listserv-auth.module.ts @@ -1,5 +1,5 @@ import { Module } from '@nestjs/common'; -import { ListservAuthService } from './auth.service'; +import { ListservAuthService } from './listserv-auth.service'; import { ConfigModule } from '../config/config.module'; @Module({ diff --git a/server/src/listserv/auth.service.ts b/server/src/listserv/listserv-auth.service.ts similarity index 100% rename from server/src/listserv/auth.service.ts rename to server/src/listserv/listserv-auth.service.ts diff --git a/server/src/send-update/send-update.controller.ts b/server/src/send-update/send-update.controller.ts index 808d8e45..66b61cec 100644 --- a/server/src/send-update/send-update.controller.ts +++ b/server/src/send-update/send-update.controller.ts @@ -2,7 +2,7 @@ import { Controller, Param, Post, Req, Res } from "@nestjs/common"; import { ConfigService } from "../config/config.service"; import { SendUpdateService } from "./send-update.service"; import { ProjectService } from "../project/project.service"; -import { ListservAuthService } from "../listserv/auth.service"; +import { ListservAuthService } from "../listserv/listserv-auth.service"; import { Request } from "express"; @Controller() @@ -32,47 +32,92 @@ export class SendUpdateController { const project = await this.projectService.findOneByName(params.id); // If no project is found, projectService returns HTTP error automatically, and this function does not continue - + // Production names use underscores, staging use dashes - const segmentName = `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}${project["data"]["attributes"]["dcp-borough"] === "Citywide" ? "CW" : project["data"]["attributes"]["dcp-validatedcommunitydistricts"]}` - const segmentIdResult = await this.sendUpdateService.getSegmentId(segmentName) + var segments = project["data"]["attributes"]["dcp-borough"] === "Citywide" ? [{ name: "CW", envSegment: `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}CW`, segmentId: "" }] : []; - if(segmentIdResult.isError) { - response.status(500).send(segmentIdResult); - return; + if(project["data"]["attributes"]["dcp-validatedcommunitydistricts"]) { + project["data"]["attributes"]["dcp-validatedcommunitydistricts"].split(",").forEach(element => { + segments.push({ name: element, envSegment: `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}${element}`, segmentId: "" }) + }); } - const emailData = { - "domain": this.sendgridEnvironment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc", - "id": params.id, - "name": project["data"]["attributes"]["dcp-projectname"], - "borocd": project["data"]["attributes"]["dcp-borough"] === "Citywide" ? "Citywide" : `${project["data"]["attributes"]["dcp-borough"]} CD ${project["data"]["attributes"]["dcp-validatedcommunitydistricts"].slice(1 )}`, - "status": project["data"]["attributes"]["dcp-publicstatus"], - "date": new Date().toLocaleDateString(), - "additionalpublicinformation": project["data"]["attributes"]["dcp-additionalpublicinformation"], - "dcpIsApplicant": project["data"]["attributes"]["dcp-applicant-customer-value"] === "DCP - Department of City Planning (NYC)" - } - - const emailHtml = this.sendUpdateService.createProjectUpdateContent(emailData); - - const createUpdate = await this.sendUpdateService.createSingleSendProjectUpdate(params.id, emailHtml, segmentIdResult.segmentId); - - if (createUpdate.isError) { - response.status(createUpdate.code).send({ + if (!segments.length) { + response.status(400).send({ isError: true, project, - createUpdate + error: "No associated segments found." }) return; } - const sendUpdate = await this.sendUpdateService.scheduleSingleSendProjectUpdate(createUpdate["0"]["body"]["id"]); + for (const segment of segments) { + const segmentIdResult = await this.sendUpdateService.getSegmentId(segment.envSegment); + if(segmentIdResult.isError) { + response.status(500).send(segmentIdResult); + return; + } + segment.segmentId = segmentIdResult.segmentId; + } + + var creationUpdates = []; + var sendUpdates = []; + + const boros = { + K: 'Brooklyn', + X: 'Bronx', + M: 'Manhattan', + Q: 'Queens', + R: 'Staten Island', + }; + + for (const segment of segments) { + const emailData = { + "domain": this.sendgridEnvironment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc", + "id": params.id, + "name": project["data"]["attributes"]["dcp-projectname"], + "borocd": segment.name === "CW" ? "Citywide" : `${boros[segment.name.slice(0,1)]} CD ${parseInt(segment.name.slice(1), 10)}`, + "status": project["data"]["attributes"]["dcp-publicstatus"], + "date": new Date().toLocaleDateString(), + "additionalpublicinformation": project["data"]["attributes"]["dcp-additionalpublicinformation"], + "dcpIsApplicant": project["data"]["attributes"]["dcp-applicant-customer-value"] === "DCP - Department of City Planning (NYC)", + "spansMoreThanOneCD": (project["data"]["attributes"]["dcp-validatedcommunitydistricts"] && (project["data"]["attributes"]["dcp-validatedcommunitydistricts"].split(",").length > 1)) + } + + const emailHtml = this.sendUpdateService.createProjectUpdateContent(emailData); + + const createUpdate = await this.sendUpdateService.createSingleSendProjectUpdate(params.id, emailHtml, segment.segmentId); + + if (createUpdate.isError) { + response.status(createUpdate.code).send({ + isError: true, + project, + createUpdate + }) + return; + } + + const sendUpdate = await this.sendUpdateService.scheduleSingleSendProjectUpdate(createUpdate["0"]["body"]["id"]); + + if (sendUpdate.isError) { + response.status(sendUpdate.code).send({ + isError: true, + project, + createUpdate, + sendUpdate + }) + return; + } + + creationUpdates.push(createUpdate); + sendUpdates.push(sendUpdate); + } response.status(201).send({ isError: false, project, - createUpdate, - sendUpdate + creationUpdates, + sendUpdates }); return; } diff --git a/server/src/send-update/send-update.module.ts b/server/src/send-update/send-update.module.ts index de2ff6fd..2bd4666a 100644 --- a/server/src/send-update/send-update.module.ts +++ b/server/src/send-update/send-update.module.ts @@ -13,8 +13,8 @@ import { CrmModule } from "../crm/crm.module"; import { DocumentModule } from "../document/document.module"; import { DispositionModule } from "../disposition/disposition.module"; import { GeometryService } from "../project/geometry/geometry.service"; -import { ListservAuthModule } from "../listserv/auth.module"; -import { ListservAuthService } from "../listserv/auth.service"; +import { ListservAuthModule } from "../listserv/listserv-auth.module"; +import { ListservAuthService } from "../listserv/listserv-auth.service"; @Module({ imports: [ diff --git a/server/src/send-update/send-update.service.ts b/server/src/send-update/send-update.service.ts index e754083d..adca0c3e 100644 --- a/server/src/send-update/send-update.service.ts +++ b/server/src/send-update/send-update.service.ts @@ -51,12 +51,12 @@ export class SendUpdateService { */ async createSingleSendProjectUpdate(id: string, emailHtml: string, segmentId: string) { const data = { - name: "Single Send Test 2024-12-06 v5", + name: "Single Send Test 2024-12-10 v3", send_to: { segment_ids: [segmentId] }, email_config: { - subject: "Single Send Test 2024-12-06 v5", + subject: "Single Send Test 2024-12-10 v3", html_content: emailHtml, generate_plain_content: true, custom_unsubscribe_url: `https://${this.environment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc"}/subscribers/{{${this.environment === "production" ? "zap_production_id" : "zap_staging_id"}}}`, @@ -115,9 +115,10 @@ export class SendUpdateService { * @param {string} date * @param {string} additionalpublicinformation * @param {string} dcpIsApplicant + * @param {boolean} spansMoreThanOneCD * @returns {object} */ - createProjectUpdateContent({domain, id, name, borocd, status, date, additionalpublicinformation, dcpIsApplicant}) { + createProjectUpdateContent({domain, id, name, borocd, status, date, additionalpublicinformation, dcpIsApplicant, spansMoreThanOneCD}) { var htmlContent = ` @@ -175,7 +176,7 @@ export class SendUpdateService {

- ${name} + ${name}${spansMoreThanOneCD ? "*" : ""} in ${borocd} `; @@ -192,6 +193,10 @@ export class SendUpdateService { htmlContent += `

New York City Department of City Planning is the applicant. Click here to learn more.

` } + if (spansMoreThanOneCD) { + htmlContent += `

*Project spans more than one CD.

` + } + htmlContent += `