Skip to content

Commit b77d633

Browse files
authored
Merge pull request #4099 from masslight/omar/fix-report-issue-secret
rename missing report issue secret
2 parents 6ff4f17 + 4e5fc55 commit b77d633

File tree

4 files changed

+110
-124
lines changed

4 files changed

+110
-124
lines changed

config/oystehr/ottehr-spec.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@
5353
"name": "VIRTUAL_SENDGRID_CANCELLATION_EMAIL_TEMPLATE_ID",
5454
"value": "#{var/VIRTUAL_SENDGRID_CANCELLATION_EMAIL_TEMPLATE_ID}"
5555
},
56-
"VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID": {
57-
"name": "VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID",
58-
"value": "#{var/VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID}"
59-
},
6056
"VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID": {
6157
"name": "VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID",
6258
"value": "#{var/VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID}"
@@ -93,10 +89,6 @@
9389
"name": "IN_PERSON_SENDGRID_ERROR_EMAIL_TEMPLATE_ID",
9490
"value": "#{var/IN_PERSON_SENDGRID_ERROR_EMAIL_TEMPLATE_ID}"
9591
},
96-
"IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID": {
97-
"name": "IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID",
98-
"value": "#{var/IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID}"
99-
},
10092
"IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR": {
10193
"name": "IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR",
10294
"value": "#{var/IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR}"

packages/utils/lib/secrets/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ export enum SecretsKeys {
2626
ENVIRONMENT = 'ENVIRONMENT',
2727
SENDGRID_SEND_EMAIL_API_KEY = 'SENDGRID_SEND_EMAIL_API_KEY',
2828
SENDGRID_ISSUE_REPORT_EMAIL_BCC = 'SENDGRID_ISSUE_REPORT_EMAIL_BCC',
29+
SENDGRID_ERROR_REPORT_TEMPLATE_ID = 'SENDGRID_ERROR_REPORT_TEMPLATE_ID',
2930
VIRTUAL_SENDGRID_CONFIRMATION_EMAIL_TEMPLATE_ID = 'VIRTUAL_SENDGRID_CONFIRMATION_EMAIL_TEMPLATE_ID',
3031
VIRTUAL_SENDGRID_CANCELLATION_EMAIL_TEMPLATE_ID = 'VIRTUAL_SENDGRID_CANCELLATION_EMAIL_TEMPLATE_ID',
31-
VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID = 'VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID',
3232
VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID = 'VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID',
3333
ORGANIZATION_ID = 'ORGANIZATION_ID',
3434
NLM_API_KEY = 'NLM_API_KEY',
@@ -38,7 +38,6 @@ export enum SecretsKeys {
3838
IN_PERSON_SENDGRID_SPANISH_CONFIRMATION_EMAIL_TEMPLATE_ID = 'IN_PERSON_SENDGRID_SPANISH_CONFIRMATION_EMAIL_TEMPLATE_ID',
3939
IN_PERSON_SENDGRID_SPANISH_CANCELLATION_EMAIL_TEMPLATE_ID = 'IN_PERSON_SENDGRID_SPANISH_CANCELLATION_EMAIL_TEMPLATE_ID',
4040
IN_PERSON_SENDGRID_ERROR_EMAIL_TEMPLATE_ID = 'IN_PERSON_SENDGRID_ERROR_EMAIL_TEMPLATE_ID',
41-
IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID = 'IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID',
4241
IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR = 'IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR',
4342
UC_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID = 'UC_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID',
4443
INTAKE_ISSUE_REPORT_EMAIL_GROUP_ID = 'INTAKE_ISSUE_REPORT_EMAIL_GROUP_ID',

packages/zambdas/.env/local.template.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
"ENVIRONMENT": "local",
1111
"SENDGRID_API_KEY": "API_KEY",
1212
"SENDGRID_ISSUE_REPORT_EMAIL_BCC": "EMAIL_BCC",
13+
"SENDGRID_ERROR_REPORT_TEMPLATE_ID": "TEMPLATE_ID",
1314
"VIRTUAL_SENDGRID_CONFIRMATION_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
1415
"VIRTUAL_SENDGRID_CANCELLATION_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
15-
"VIRTUAL_SENDGRID_ERROR_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
1616
"VIRTUAL_SENDGRID_VIDEO_CHAT_INVITATION_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
1717
"ORGANIZATION_ID": "ORGANIZATION_ID",
1818
"NLM_API_KEY": "",
@@ -22,7 +22,6 @@
2222
"IN_PERSON_SENDGRID_SPANISH_CONFIRMATION_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
2323
"IN_PERSON_SENDGRID_SPANISH_CANCELLATION_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
2424
"IN_PERSON_SENDGRID_ERROR_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
25-
"IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
2625
"IN_PERSON_PREBOOK_DISPLAY_TOMORROW_SLOTS_AT_HOUR": "9",
2726
"UC_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID": "TEMPLATE_ID",
2827
"INTAKE_ISSUE_REPORT_EMAIL_GROUP_ID": "GROUP_ID",

packages/zambdas/src/subscriptions/communication/communication-subscription/index.ts

Lines changed: 108 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -53,130 +53,126 @@ export const index = wrapHandler(ZAMBDA_NAME, async (input: ZambdaInput): Promis
5353
if (codingContainedInList(COMMUNICATION_ISSUE_REPORT_CODE, communicationCodes)) {
5454
console.log('alerting for issue report');
5555
const groupID = getSecret(SecretsKeys.INTAKE_ISSUE_REPORT_EMAIL_GROUP_ID, secrets);
56-
const templateID = getSecret(SecretsKeys.IN_PERSON_SENDGRID_ISSUE_REPORT_EMAIL_TEMPLATE_ID, secrets);
5756

58-
// Only alert where both variables exist and are non null value
59-
if (groupID && templateID) {
60-
const groupGetRequest: BatchInputGetRequest = {
61-
method: 'GET',
62-
url: `/Group?_id=${groupID}`,
63-
};
64-
const locationID = communication.about
65-
?.find((ref) => ref.type === 'Location')
66-
?.reference?.replace('Location/', '');
67-
const locationGetRequest: BatchInputGetRequest = {
68-
method: 'GET',
69-
url: `/Location?_id=${locationID}`,
70-
};
71-
const practitionerID = communication.sender?.reference?.replace('Practitioner/', '');
72-
const practitionerGetRequest: BatchInputGetRequest = {
73-
method: 'GET',
74-
url: `/Practitioner?_id=${practitionerID}`,
75-
};
76-
const appointmentID = communication.about
77-
?.find((ref) => ref.type === 'Appointment')
78-
?.reference?.replace('Appointment/', '');
79-
80-
console.log('getting fhir resources for issue report alerting');
81-
console.log('groupID, locationID, practitionerID', groupID, locationID, practitionerID);
82-
const bundle = await oystehr.fhir.batch({
83-
requests: [groupGetRequest, locationGetRequest, practitionerGetRequest],
84-
});
85-
86-
const bundleResources: bundleResourcesConfig = {};
87-
if (bundle.entry) {
88-
for (const entry of bundle.entry) {
89-
if (
90-
entry.response?.outcome?.id === 'ok' &&
91-
entry.resource &&
92-
entry.resource.resourceType === 'Bundle' &&
93-
entry.resource.type === 'searchset'
94-
) {
95-
const innerBundle = entry.resource as Bundle;
96-
const innerEntries = innerBundle.entry;
97-
if (innerEntries) {
98-
for (const item of innerEntries) {
99-
const resource = item.resource;
100-
if (resource) {
101-
if (resource?.resourceType === 'Group') {
102-
bundleResources.group = resource as Group;
103-
}
104-
if (resource?.resourceType === 'Location') {
105-
bundleResources.location = resource as Location;
106-
}
107-
if (resource?.resourceType === 'Practitioner') {
108-
bundleResources.practitioner = resource as Practitioner;
109-
}
57+
const groupGetRequest: BatchInputGetRequest = {
58+
method: 'GET',
59+
url: `/Group?_id=${groupID}`,
60+
};
61+
const locationID = communication.about
62+
?.find((ref) => ref.type === 'Location')
63+
?.reference?.replace('Location/', '');
64+
const locationGetRequest: BatchInputGetRequest = {
65+
method: 'GET',
66+
url: `/Location?_id=${locationID}`,
67+
};
68+
const practitionerID = communication.sender?.reference?.replace('Practitioner/', '');
69+
const practitionerGetRequest: BatchInputGetRequest = {
70+
method: 'GET',
71+
url: `/Practitioner?_id=${practitionerID}`,
72+
};
73+
const appointmentID = communication.about
74+
?.find((ref) => ref.type === 'Appointment')
75+
?.reference?.replace('Appointment/', '');
76+
77+
console.log('getting fhir resources for issue report alerting');
78+
console.log('groupID, locationID, practitionerID', groupID, locationID, practitionerID);
79+
const bundle = await oystehr.fhir.batch({
80+
requests: [groupGetRequest, locationGetRequest, practitionerGetRequest],
81+
});
82+
83+
const bundleResources: bundleResourcesConfig = {};
84+
if (bundle.entry) {
85+
for (const entry of bundle.entry) {
86+
if (
87+
entry.response?.outcome?.id === 'ok' &&
88+
entry.resource &&
89+
entry.resource.resourceType === 'Bundle' &&
90+
entry.resource.type === 'searchset'
91+
) {
92+
const innerBundle = entry.resource as Bundle;
93+
const innerEntries = innerBundle.entry;
94+
if (innerEntries) {
95+
for (const item of innerEntries) {
96+
const resource = item.resource;
97+
if (resource) {
98+
if (resource?.resourceType === 'Group') {
99+
bundleResources.group = resource as Group;
100+
}
101+
if (resource?.resourceType === 'Location') {
102+
bundleResources.location = resource as Location;
103+
}
104+
if (resource?.resourceType === 'Practitioner') {
105+
bundleResources.practitioner = resource as Practitioner;
110106
}
111107
}
112108
}
113109
}
114110
}
115111
}
116-
const submitter = bundleResources.practitioner;
117-
const fhirLocation = bundleResources.location;
118-
const fhirGroup = bundleResources.group;
119-
120-
let submitterName = submitter && getFullestAvailableName(submitter);
121-
let submitterEmail = '';
122-
try {
123-
const PROJECT_API = getSecret('PROJECT_API', secrets);
124-
const headers = {
125-
accept: 'application/json',
126-
'content-type': 'application/json',
127-
Authorization: `Bearer ${oystehrToken}`,
128-
};
129-
const getUserByProfileResponse = await fetch(
130-
`${PROJECT_API}/user/v2/list?profile=Practitioner/${practitionerID}`,
131-
{
132-
method: 'GET',
133-
headers: headers,
134-
}
135-
);
136-
if (!getUserByProfileResponse.ok) {
137-
console.error('Failed to get user from a given Practitioner ID profile');
138-
}
139-
const retrievedUser = await getUserByProfileResponse.json();
140-
if (submitterName == undefined) {
141-
submitterName = `${retrievedUser?.data?.[0]?.name}`;
112+
}
113+
const submitter = bundleResources.practitioner;
114+
const fhirLocation = bundleResources.location;
115+
const fhirGroup = bundleResources.group;
116+
117+
let submitterName = submitter && getFullestAvailableName(submitter);
118+
let submitterEmail = '';
119+
try {
120+
const PROJECT_API = getSecret('PROJECT_API', secrets);
121+
const headers = {
122+
accept: 'application/json',
123+
'content-type': 'application/json',
124+
Authorization: `Bearer ${oystehrToken}`,
125+
};
126+
const getUserByProfileResponse = await fetch(
127+
`${PROJECT_API}/user/v2/list?profile=Practitioner/${practitionerID}`,
128+
{
129+
method: 'GET',
130+
headers: headers,
142131
}
143-
submitterEmail = `${retrievedUser?.data?.[0]?.email}`;
144-
} catch (error) {
145-
console.error('Fetch call failed with error: ', error);
132+
);
133+
if (!getUserByProfileResponse.ok) {
134+
console.error('Failed to get user from a given Practitioner ID profile');
146135
}
147-
const submitterDetails = `Submitter name: ${submitterName}, Submitter email: ${submitterEmail}, Submitter id: ${submitter?.id}`;
148-
149-
console.log('sending slack message');
150-
const slackMessage = `An issue report has been submitted from ${fhirLocation?.name}. Check payload in communication resource ${communication.id} for more information`;
151-
try {
152-
await sendSlackNotification(slackMessage, ENVIRONMENT);
153-
communicationStatusToUpdate = 'completed';
154-
} catch {
155-
console.log('could not send slack notification');
136+
const retrievedUser = await getUserByProfileResponse.json();
137+
if (submitterName == undefined) {
138+
submitterName = `${retrievedUser?.data?.[0]?.name}`;
156139
}
140+
submitterEmail = `${retrievedUser?.data?.[0]?.email}`;
141+
} catch (error) {
142+
console.error('Fetch call failed with error: ', error);
143+
}
144+
const submitterDetails = `Submitter name: ${submitterName}, Submitter email: ${submitterEmail}, Submitter id: ${submitter?.id}`;
145+
146+
console.log('sending slack message');
147+
const slackMessage = `An issue report has been submitted from ${fhirLocation?.name}. Check payload in communication resource ${communication.id} for more information`;
148+
try {
149+
await sendSlackNotification(slackMessage, ENVIRONMENT);
150+
communicationStatusToUpdate = 'completed';
151+
} catch {
152+
console.log('could not send slack notification');
153+
}
157154

158-
console.log('getting emails');
159-
const practitionersEmails = await getEmailsFromGroup(fhirGroup, oystehr);
160-
console.log('practitionersEmails', practitionersEmails);
155+
console.log('getting emails');
156+
const practitionersEmails = await getEmailsFromGroup(fhirGroup, oystehr);
157+
console.log('practitionersEmails', practitionersEmails);
161158

162-
const toEmail = [];
163-
if (practitionersEmails) {
164-
toEmail.push(...practitionersEmails);
165-
}
166-
const errorMessage = `Details: ${communication.payload?.[0].contentString} <br> Submitted By: ${submitterDetails} <br> Location: ${fhirLocation?.name} - ${fhirLocation?.address?.city}, ${fhirLocation?.address?.state} <br> Appointment Id: ${appointmentID} <br> Communication Fhir Resource: ${communication.id}`;
167-
168-
console.log(`Sending issue report email to ${toEmail} with template id ${templateID}`);
169-
try {
170-
const emailClient = getEmailClient(secrets);
171-
await emailClient.sendErrorEmail(toEmail, {
172-
environment: ENVIRONMENT,
173-
'error-message': errorMessage,
174-
timestamp: DateTime.now().setZone('UTC').toFormat("EEEE, MMMM d, yyyy 'at' h:mm a ZZZZ"),
175-
});
176-
communicationStatusToUpdate = 'completed';
177-
} catch (error) {
178-
console.error(`Error sending email to ${toEmail}: ${JSON.stringify(error)}`);
179-
}
159+
const toEmail = [];
160+
if (practitionersEmails) {
161+
toEmail.push(...practitionersEmails);
162+
}
163+
const errorMessage = `Details: ${communication.payload?.[0].contentString} <br> Submitted By: ${submitterDetails} <br> Location: ${fhirLocation?.name} - ${fhirLocation?.address?.city}, ${fhirLocation?.address?.state} <br> Appointment Id: ${appointmentID} <br> Communication Fhir Resource: ${communication.id}`;
164+
165+
console.log(`Sending issue report email to ${toEmail}`);
166+
try {
167+
const emailClient = getEmailClient(secrets);
168+
await emailClient.sendErrorEmail(toEmail, {
169+
environment: ENVIRONMENT,
170+
'error-message': errorMessage,
171+
timestamp: DateTime.now().setZone('UTC').toFormat("EEEE, MMMM d, yyyy 'at' h:mm a ZZZZ"),
172+
});
173+
communicationStatusToUpdate = 'completed';
174+
} catch (error) {
175+
console.error(`Error sending email to ${toEmail}: ${JSON.stringify(error)}`);
180176
}
181177
}
182178

0 commit comments

Comments
 (0)