Skip to content

Commit 8383f8d

Browse files
authored
feat(feedback): Allow passing tags field to any feedback config param (#12197)
We were missing the ability to set tags within feedback before, this corrects it. See getsentry/sentry-docs#10137 for the docs update. Now a developer can set `tags: {...}` anytime an options param is passed into feedback. This includes: - when we init the integration `feedbackIntegration({tags: {hello: 'world'}})` - when attachTo is called: `feedback.attachTo(element, {tags: {hello: 'world'}})` - when createWidget is called: `feedback.createWidget({tags: {hello: 'world'}})` - when createForm is called: `feedback.createForm({tags: {hello: 'world'}})` Users can also pass tags to `sendFeedback()` which is slightly nicer than having to set them on scope first. - `Sentry.sendFeedback({tags: {hello: 'world'}})` - `captureFeedback()` is unaffected, keeping it closer in style to the other `capture*()` methods. I also took the chance to re-use related types in more places. Checkout the first 2 commits on the branch to see those changes individually. Fixes getsentry/sentry#71254
1 parent b4b51c2 commit 8383f8d

File tree

10 files changed

+44
-16
lines changed

10 files changed

+44
-16
lines changed

dev-packages/browser-integration-tests/suites/feedback/captureFeedback/init.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ window.Sentry = Sentry;
44

55
Sentry.init({
66
dsn: 'https://public@dsn.ingest.sentry.io/1337',
7-
integrations: [Sentry.feedbackIntegration()],
7+
integrations: [
8+
Sentry.feedbackIntegration({
9+
tags: { from: 'integration init' },
10+
}),
11+
],
812
});

dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ sentryTest('should capture feedback', async ({ getLocalTestUrl, page }) => {
5959
},
6060
},
6161
level: 'info',
62+
tags: {
63+
from: 'integration init',
64+
},
6265
timestamp: expect.any(Number),
6366
event_id: expect.stringMatching(/\w{32}/),
6467
environment: 'production',

dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/hasSampling/test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ sentryTest('should capture feedback', async ({ forceFlushReplay, getLocalTestUrl
9595
},
9696
},
9797
level: 'info',
98+
tags: {},
9899
timestamp: expect.any(Number),
99100
event_id: expect.stringMatching(/\w{32}/),
100101
environment: 'production',

packages/core/src/feedback.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import { getClient, getCurrentScope } from './currentScopes';
66
* Send user feedback to Sentry.
77
*/
88
export function captureFeedback(
9-
feedbackParams: SendFeedbackParams,
9+
params: SendFeedbackParams,
1010
hint: EventHint & { includeReplay?: boolean } = {},
1111
scope = getCurrentScope(),
1212
): string {
13-
const { message, name, email, url, source, associatedEventId } = feedbackParams;
13+
const { message, name, email, url, source, associatedEventId, tags } = params;
1414

1515
const feedbackEvent: FeedbackEvent = {
1616
contexts: {
@@ -25,6 +25,7 @@ export function captureFeedback(
2525
},
2626
type: 'feedback',
2727
level: 'info',
28+
tags,
2829
};
2930

3031
const client = (scope && scope.getClient()) || getClient();

packages/feedback/src/core/integration.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,18 @@ export const buildFeedbackIntegration = ({
6464
const feedbackIntegration = (({
6565
// FeedbackGeneralConfiguration
6666
id = 'sentry-feedback',
67-
showBranding = true,
6867
autoInject = true,
68+
showBranding = true,
69+
isEmailRequired = false,
70+
isNameRequired = false,
6971
showEmail = true,
7072
showName = true,
7173
enableScreenshot = true,
7274
useSentryUser = {
7375
email: 'email',
7476
name: 'username',
7577
},
76-
isNameRequired = false,
77-
isEmailRequired = false,
78+
tags,
7879

7980
// FeedbackThemeConfiguration
8081
colorScheme = 'system',
@@ -115,6 +116,7 @@ export const buildFeedbackIntegration = ({
115116
showName,
116117
enableScreenshot,
117118
useSentryUser,
119+
tags,
118120

119121
colorScheme,
120122
themeDark,

packages/feedback/src/core/sendFeedback.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { captureFeedback } from '@sentry/core';
22
import { getClient } from '@sentry/core';
3-
import type { EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
4-
import type { Event } from '@sentry/types';
3+
import { getCurrentScope } from '@sentry/core';
4+
import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
55
import { getLocationHref } from '@sentry/utils';
66
import { FEEDBACK_API_SOURCE } from '../constants';
77

88
/**
99
* Public API to send a Feedback item to Sentry
1010
*/
1111
export const sendFeedback: SendFeedback = (
12-
options: SendFeedbackParams,
12+
params: SendFeedbackParams,
1313
hint: EventHint & { includeReplay?: boolean } = { includeReplay: true },
1414
): Promise<string> => {
15-
if (!options.message) {
15+
if (!params.message) {
1616
throw new Error('Unable to submit feedback with empty message');
1717
}
1818

@@ -23,11 +23,14 @@ export const sendFeedback: SendFeedback = (
2323
throw new Error('No client setup, cannot send feedback.');
2424
}
2525

26+
if (params.tags && Object.keys(params.tags).length) {
27+
getCurrentScope().setTags(params.tags);
28+
}
2629
const eventId = captureFeedback(
2730
{
2831
source: FEEDBACK_API_SOURCE,
2932
url: getLocationHref(),
30-
...options,
33+
...params,
3134
},
3235
hint,
3336
);

packages/feedback/src/modal/components/Form.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export function Form({
4646
screenshotInput,
4747
}: Props): VNode {
4848
const {
49+
tags,
4950
addScreenshotButtonLabel,
5051
removeScreenshotButtonLabel,
5152
cancelButtonLabel,
@@ -122,6 +123,7 @@ export function Form({
122123
email: data.email,
123124
message: data.message,
124125
source: FEEDBACK_WIDGET_SOURCE,
126+
tags,
125127
},
126128
{ attachments: data.attachments },
127129
);

packages/feedback/src/util/mergeOptions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export function mergeOptions(
1111
return {
1212
...defaultOptions,
1313
...optionOverrides,
14+
tags: {
15+
...defaultOptions.tags,
16+
...optionOverrides.tags,
17+
},
1418
onFormOpen: () => {
1519
optionOverrides.onFormOpen && optionOverrides.onFormOpen();
1620
defaultOptions.onFormOpen && defaultOptions.onFormOpen();

packages/types/src/feedback/config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Primitive } from '../misc';
12
import type { FeedbackFormData } from './form';
23
import type { FeedbackTheme } from './theme';
34

@@ -55,6 +56,11 @@ export interface FeedbackGeneralConfiguration {
5556
email: string;
5657
name: string;
5758
};
59+
60+
/**
61+
* Set an object that will be merged sent as tags data with the event.
62+
*/
63+
tags?: { [key: string]: Primitive };
5864
}
5965

6066
/**

packages/types/src/feedback/sendFeedback.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Event, EventHint } from '../event';
2+
import type { Primitive } from '../misc';
23
import type { User } from '../user';
34

45
/**
@@ -38,13 +39,14 @@ export interface SendFeedbackParams {
3839
url?: string;
3940
source?: string;
4041
associatedEventId?: string;
41-
}
4242

43-
interface SendFeedbackOptions extends EventHint {
4443
/**
45-
* Should include replay with the feedback?
44+
* Set an object that will be merged sent as tags data with the event.
4645
*/
47-
includeReplay?: boolean;
46+
tags?: { [key: string]: Primitive };
4847
}
4948

50-
export type SendFeedback = (params: SendFeedbackParams, options?: SendFeedbackOptions) => Promise<string>;
49+
export type SendFeedback = (
50+
params: SendFeedbackParams,
51+
hint?: EventHint & { includeReplay?: boolean },
52+
) => Promise<string>;

0 commit comments

Comments
 (0)