Skip to content

Commit

Permalink
feat(sentry_webhook): update Salesforce record IDs for new contact fo…
Browse files Browse the repository at this point in the history
…rm (Jigsaw-Code#1510)

* chore(sentry_webhook): update Salesforce record IDs for new contact form

* Add new `accessKeySource` and `build`.

* Add new fields `subject` and `isUpdatedForm`.

* Change `type` field to new `role` field.

* Normalize `cloudProvider` value based on allowed picklist values.

* Update tests.
  • Loading branch information
sbruens authored Feb 22, 2024
1 parent e2486ba commit ea81c99
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 21 deletions.
20 changes: 13 additions & 7 deletions src/sentry_webhook/post_sentry_event_to_salesforce.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('postSentryEventToSalesforce', () => {
'&email=foo%40bar.com' +
'&00N0b00000BqOA4=' +
'&description=my%20message' +
'&type=Outline%20client'
'&00N5a00000DXxmr=I%20am%20using%20the%20Outline%20client%20application%20on%20my%20mobile%20or%20desktop%20device'
);
expect(mockRequest.end).toHaveBeenCalled();
});
Expand All @@ -81,7 +81,7 @@ describe('postSentryEventToSalesforce', () => {
'&email=foo%40bar.com' +
'&00N3F000002Rqhq=' +
'&description=my%20message' +
'&type=Outline%20client'
'&UNKNOWN=I%20am%20using%20the%20Outline%20client%20application%20on%20my%20mobile%20or%20desktop%20device'
);
expect(mockRequest.end).toHaveBeenCalled();
});
Expand All @@ -91,9 +91,12 @@ describe('postSentryEventToSalesforce', () => {
user: {email: 'foo@bar.com'},
message: 'my message',
tags: [
['category', 'test category'],
['category', 'no-server'],
['subject', 'test subject'],
['os.name', 'Mac OS X'],
['sentry:release', 'test version'],
['build.number', '0.0.0-debug'],
['accessKeySource', 'test source'],
['unknown:tag', 'foo'],
],
};
Expand All @@ -107,10 +110,13 @@ describe('postSentryEventToSalesforce', () => {
'&email=foo%40bar.com' +
'&00N0b00000BqOA4=' +
'&description=my%20message' +
'&type=Outline%20client' +
'&00N0b00000BqOA2=test%20category' +
'&00N0b00000BqOfW=macOs' +
'&00N0b00000BqOfR=test%20version'
'&00N5a00000DXxmr=I%20am%20using%20the%20Outline%20client%20application%20on%20my%20mobile%20or%20desktop%20device' +
'&00N5a00000DXy19=I%20need%20an%20access%20key' +
'&subject=test%20subject' +
'&00N5a00000DXxmo=MacOS' +
'&00N5a00000DXxmq=test%20version' +
'&00N5a00000DXy64=0.0.0-debug' +
'&00N5a00000DXxms=test%20source'
);
expect(mockRequest.end).toHaveBeenCalled();
});
Expand Down
94 changes: 80 additions & 14 deletions src/sentry_webhook/post_sentry_event_to_salesforce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ interface SalesforceFormFields {
orgId: string;
recordType: string;
email: string;
subject: string;
description: string;
category: string;
issue: string;
accessKeySource: string;
cloudProvider: string;
sentryEventUrl: string;
os: string;
version: string;
type: string;
build: string;
role: string;
isUpdatedForm: string;
}

// Defines the Salesforce form values.
Expand All @@ -42,25 +46,33 @@ const SALESFORCE_FORM_FIELDS_DEV: SalesforceFormFields = {
orgId: 'orgid',
recordType: 'recordType',
email: 'email',
subject: 'subject',
description: 'description',
category: '00N3F000002Rqho',
issue: '00N3F000002Rqho',
accessKeySource: '00N75000000wYiY',
cloudProvider: '00N3F000002Rqhs',
sentryEventUrl: '00N3F000002Rqhq',
os: '00N3F000002cLcN',
version: '00N3F000002cLcI',
type: 'type',
build: '00N75000000wmdC',
role: 'UNKNOWN',
isUpdatedForm: '00N75000000wmd7',
};
const SALESFORCE_FORM_FIELDS_PROD: SalesforceFormFields = {
orgId: 'orgid',
recordType: 'recordType',
email: 'email',
subject: 'subject',
description: 'description',
category: '00N0b00000BqOA2',
cloudProvider: '00N0b00000BqOA7',
issue: '00N5a00000DXy19',
accessKeySource: '00N5a00000DXxms',
cloudProvider: '00N5a00000DXxmn',
sentryEventUrl: '00N0b00000BqOA4',
os: '00N0b00000BqOfW',
version: '00N0b00000BqOfR',
type: 'type',
os: '00N5a00000DXxmo',
version: '00N5a00000DXxmq',
build: '00N5a00000DXy64',
role: '00N5a00000DXxmr',
isUpdatedForm: '00N5a00000DXy5a',
};
const SALESFORCE_FORM_VALUES_DEV: SalesforceFormValues = {
orgId: '00D750000004dFg',
Expand All @@ -71,6 +83,22 @@ const SALESFORCE_FORM_VALUES_PROD: SalesforceFormValues = {
recordType: '0120b0000006e8i',
};

const ISSUE_TYPE_TO_PICKLIST_VALUE: {[key: string]: string} = {
'cannot-add-server': 'I am having trouble adding a server using my access key',
connection: 'I am having trouble connecting to my Outline VPN server',
general: 'General feedback & suggestions',
managing: 'I need assistance managing my Outline VPN server or helping others connect to it',
'no-server': 'I need an access key',
performance: 'My internet access is slow while connected to my Outline VPN server',
};

const CLOUD_PROVIDER_TO_PICKLIST_VALUE: {[key: string]: string} = {
aws: 'Amazon Web Services',
digitalocean: 'DigitalOcean',
gcloud: 'Google Cloud',
other: 'Other',
};

// Returns whether a Sentry event should be sent to Salesforce by checking that it contains an
// email address.
export function shouldPostEventToSalesforce(event: SentryEvent): boolean {
Expand Down Expand Up @@ -138,14 +166,34 @@ function getSalesforceFormData(
form.push(encodeFormData(formFields.email, email));
form.push(encodeFormData(formFields.sentryEventUrl, getSentryEventUrl(project, event.event_id)));
form.push(encodeFormData(formFields.description, event.message));
form.push(encodeFormData(formFields.type, isClient ? 'Outline client' : 'Outline manager'));
form.push(
encodeFormData(
formFields.role,
isClient
? 'I am using the Outline client application on my mobile or desktop device'
: 'I am an Outline server manager'
)
);
if (event.tags) {
const tags = new Map<string, string>(event.tags);
form.push(encodeFormData(formFields.category, tags.get('category')));
form.push(encodeFormData(formFields.issue, toIssuePicklistValue(tags.get('category'))));
form.push(encodeFormData(formFields.subject, tags.get('subject')));
form.push(encodeFormData(formFields.os, toOSPicklistValue(tags.get('os.name'))));
form.push(encodeFormData(formFields.version, tags.get('sentry:release')));
if (!isClient) {
form.push(encodeFormData(formFields.cloudProvider, tags.get('cloudProvider')));
form.push(encodeFormData(formFields.build, tags.get('build.number')));
const formVersion = Number(tags.get('formVersion') ?? 1);
if (formVersion === 2) {
form.push(encodeFormData(formFields.isUpdatedForm, 'true'));
}
if (isClient) {
form.push(encodeFormData(formFields.accessKeySource, tags.get('accessKeySource')));
} else {
form.push(
encodeFormData(
formFields.cloudProvider,
toCloudProviderPicklistValue(tags.get('cloudProvider'))
)
);
}
}
return form.join('&');
Expand All @@ -169,11 +217,29 @@ function toOSPicklistValue(value: string | undefined): string | undefined {
return 'Windows';
}
if (normalizedValue.includes('mac')) {
return 'macOs';
return 'MacOS';
}
return 'Linux';
}

// Returns a picklist value that is allowed by SalesForce for the issue record.
function toIssuePicklistValue(value: string | undefined): string | undefined {
if (!value) {
console.warn('No issue type found');
return undefined;
}
return ISSUE_TYPE_TO_PICKLIST_VALUE[value];
}

// Returns a picklist value that is allowed by SalesForce for the cloud provider record.
function toCloudProviderPicklistValue(value: string | undefined): string | undefined {
if (!value) {
console.warn('No cloud provider found');
return undefined;
}
return CLOUD_PROVIDER_TO_PICKLIST_VALUE[value];
}

function encodeFormData(field: string, value?: string) {
return `${encodeURIComponent(field)}=${encodeURIComponent(value || '')}`;
}
Expand Down

0 comments on commit ea81c99

Please sign in to comment.