Skip to content

Commit

Permalink
feat(feedback): Allow passing tags field to any feedback config par…
Browse files Browse the repository at this point in the history
…am (#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
  • Loading branch information
ryan953 committed Jun 17, 2024
1 parent b4b51c2 commit 8383f8d
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
integrations: [Sentry.feedbackIntegration()],
integrations: [
Sentry.feedbackIntegration({
tags: { from: 'integration init' },
}),
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ sentryTest('should capture feedback', async ({ getLocalTestUrl, page }) => {
},
},
level: 'info',
tags: {
from: 'integration init',
},
timestamp: expect.any(Number),
event_id: expect.stringMatching(/\w{32}/),
environment: 'production',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ sentryTest('should capture feedback', async ({ forceFlushReplay, getLocalTestUrl
},
},
level: 'info',
tags: {},
timestamp: expect.any(Number),
event_id: expect.stringMatching(/\w{32}/),
environment: 'production',
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { getClient, getCurrentScope } from './currentScopes';
* Send user feedback to Sentry.
*/
export function captureFeedback(
feedbackParams: SendFeedbackParams,
params: SendFeedbackParams,
hint: EventHint & { includeReplay?: boolean } = {},
scope = getCurrentScope(),
): string {
const { message, name, email, url, source, associatedEventId } = feedbackParams;
const { message, name, email, url, source, associatedEventId, tags } = params;

const feedbackEvent: FeedbackEvent = {
contexts: {
Expand All @@ -25,6 +25,7 @@ export function captureFeedback(
},
type: 'feedback',
level: 'info',
tags,
};

const client = (scope && scope.getClient()) || getClient();
Expand Down
8 changes: 5 additions & 3 deletions packages/feedback/src/core/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,18 @@ export const buildFeedbackIntegration = ({
const feedbackIntegration = (({
// FeedbackGeneralConfiguration
id = 'sentry-feedback',
showBranding = true,
autoInject = true,
showBranding = true,
isEmailRequired = false,
isNameRequired = false,
showEmail = true,
showName = true,
enableScreenshot = true,
useSentryUser = {
email: 'email',
name: 'username',
},
isNameRequired = false,
isEmailRequired = false,
tags,

// FeedbackThemeConfiguration
colorScheme = 'system',
Expand Down Expand Up @@ -115,6 +116,7 @@ export const buildFeedbackIntegration = ({
showName,
enableScreenshot,
useSentryUser,
tags,

colorScheme,
themeDark,
Expand Down
13 changes: 8 additions & 5 deletions packages/feedback/src/core/sendFeedback.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { captureFeedback } from '@sentry/core';
import { getClient } from '@sentry/core';
import type { EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
import type { Event } from '@sentry/types';
import { getCurrentScope } from '@sentry/core';
import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types';
import { getLocationHref } from '@sentry/utils';
import { FEEDBACK_API_SOURCE } from '../constants';

/**
* Public API to send a Feedback item to Sentry
*/
export const sendFeedback: SendFeedback = (
options: SendFeedbackParams,
params: SendFeedbackParams,
hint: EventHint & { includeReplay?: boolean } = { includeReplay: true },
): Promise<string> => {
if (!options.message) {
if (!params.message) {
throw new Error('Unable to submit feedback with empty message');
}

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

if (params.tags && Object.keys(params.tags).length) {
getCurrentScope().setTags(params.tags);
}
const eventId = captureFeedback(
{
source: FEEDBACK_API_SOURCE,
url: getLocationHref(),
...options,
...params,
},
hint,
);
Expand Down
2 changes: 2 additions & 0 deletions packages/feedback/src/modal/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function Form({
screenshotInput,
}: Props): VNode {
const {
tags,
addScreenshotButtonLabel,
removeScreenshotButtonLabel,
cancelButtonLabel,
Expand Down Expand Up @@ -122,6 +123,7 @@ export function Form({
email: data.email,
message: data.message,
source: FEEDBACK_WIDGET_SOURCE,
tags,
},
{ attachments: data.attachments },
);
Expand Down
4 changes: 4 additions & 0 deletions packages/feedback/src/util/mergeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export function mergeOptions(
return {
...defaultOptions,
...optionOverrides,
tags: {
...defaultOptions.tags,
...optionOverrides.tags,
},
onFormOpen: () => {
optionOverrides.onFormOpen && optionOverrides.onFormOpen();
defaultOptions.onFormOpen && defaultOptions.onFormOpen();
Expand Down
6 changes: 6 additions & 0 deletions packages/types/src/feedback/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Primitive } from '../misc';
import type { FeedbackFormData } from './form';
import type { FeedbackTheme } from './theme';

Expand Down Expand Up @@ -55,6 +56,11 @@ export interface FeedbackGeneralConfiguration {
email: string;
name: string;
};

/**
* Set an object that will be merged sent as tags data with the event.
*/
tags?: { [key: string]: Primitive };
}

/**
Expand Down
12 changes: 7 additions & 5 deletions packages/types/src/feedback/sendFeedback.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Event, EventHint } from '../event';
import type { Primitive } from '../misc';
import type { User } from '../user';

/**
Expand Down Expand Up @@ -38,13 +39,14 @@ export interface SendFeedbackParams {
url?: string;
source?: string;
associatedEventId?: string;
}

interface SendFeedbackOptions extends EventHint {
/**
* Should include replay with the feedback?
* Set an object that will be merged sent as tags data with the event.
*/
includeReplay?: boolean;
tags?: { [key: string]: Primitive };
}

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

0 comments on commit 8383f8d

Please sign in to comment.