Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sentry_webhook): update Salesforce record IDs for new contact form #1510

Merged
merged 6 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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];
sbruens marked this conversation as resolved.
Show resolved Hide resolved
}

// 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];
sbruens marked this conversation as resolved.
Show resolved Hide resolved
}

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