@pipedream/linkedin_ads 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,62 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import app from "../../linkedin_ads.app.mjs";
3
+ import utils from "../../common/utils.mjs";
4
+
5
+ export default {
6
+ props: {
7
+ app,
8
+ },
9
+ methods: {
10
+ getDateStr(date) {
11
+ return [
12
+ `day:${date.getDate()}`,
13
+ `month:${date.getMonth() + 1}`,
14
+ `year:${date.getFullYear()}`,
15
+ ].join(",");
16
+ },
17
+ getDateRangeParam(startStr, endStr) {
18
+ const { getDateStr } = this;
19
+ const start = getDateStr(new Date(startStr));
20
+
21
+ if (!endStr) {
22
+ return `(start:(${start}))`;
23
+ }
24
+
25
+ const end = getDateStr(new Date(endStr));
26
+ return `(start:(${start}),end:(${end}))`;
27
+ },
28
+ getListParam(list = []) {
29
+ return `List(${list?.map(encodeURIComponent).join(",")})`;
30
+ },
31
+ getListParams(props = {}) {
32
+ return Object.entries(props)
33
+ .reduce((acc, [
34
+ key,
35
+ value,
36
+ ]) => {
37
+ if (
38
+ typeof(value) === "function"
39
+ || value === undefined
40
+ || value === null
41
+ ) {
42
+ return acc;
43
+ }
44
+ return {
45
+ ...acc,
46
+ [key]: this.getListParam(
47
+ typeof(value) === "string"
48
+ ? JSON.parse(value)
49
+ : value,
50
+ ),
51
+ };
52
+ }, {});
53
+ },
54
+ createReport(args = {}) {
55
+ return this.app._makeRequest({
56
+ path: "/adAnalytics",
57
+ paramsSerializer: utils.getParamsSerializer(),
58
+ ...args,
59
+ });
60
+ },
61
+ },
62
+ };
@@ -0,0 +1,105 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import common from "../common/report.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "linkedin_ads-create-report",
7
+ name: "Create A Report",
8
+ description: "Queries the Analytics Finder to get analytics for the specified entity i.e company, account, campaign. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/ads-reporting#analytics-finder)",
9
+ version: "0.0.4",
10
+ type: "action",
11
+ props: {
12
+ ...common.props,
13
+ adAccountId: {
14
+ propDefinition: [
15
+ common.props.app,
16
+ "adAccountId",
17
+ ],
18
+ },
19
+ pivot: {
20
+ propDefinition: [
21
+ common.props.app,
22
+ "pivot",
23
+ ],
24
+ },
25
+ timeGranularity: {
26
+ propDefinition: [
27
+ common.props.app,
28
+ "timeGranularity",
29
+ ],
30
+ },
31
+ dateRangeStart: {
32
+ type: "string",
33
+ label: "Date Range Start",
34
+ description: "Represents the inclusive start time range of the analytics. If unset, it indicates an open range up to the end time. Should be in the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g. 2022-12-27.",
35
+ },
36
+ dateRangeEnd: {
37
+ type: "string",
38
+ label: "Date Range End",
39
+ description: "Represents the inclusive end time range of the analytics. Must be after start time if it's present. If unset, it indicates an open range from start time to everything after. Should be in the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, e.g. 2022-12-27.",
40
+ optional: true,
41
+ },
42
+ shares: {
43
+ type: "string[]",
44
+ label: "Shares",
45
+ description: "An [Array of Share URN](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api). Required unless another facet is provided.",
46
+ optional: true,
47
+ },
48
+ campaigns: {
49
+ type: "string[]",
50
+ label: "Campaigns",
51
+ description: "An [Array of Sponsored Campaign URN](https://docs.microsoft.com/en-us/linkedin/shared/references/v2/ads/adcampaigns?context=linkedin/marketing/context). Required unless another facet is provided.",
52
+ optional: true,
53
+ },
54
+ creatives: {
55
+ type: "string[]",
56
+ label: "Creatives",
57
+ description: "An [Array of Sponsored Creative URN](https://docs.microsoft.com/en-us/linkedin/shared/references/v2/ads/adcreatives?context=linkedin/marketing/context). Required unless another facet is provided.",
58
+ optional: true,
59
+ },
60
+ campaignGroups: {
61
+ type: "string[]",
62
+ label: "Campaign Groups",
63
+ description: "An [Array of Campaign Group URN](https://docs.microsoft.com/en-us/linkedin/shared/references/v2/ads/adcampaigngroups?context=linkedin/marketing/context). Required unless another facet is provided.",
64
+ optional: true,
65
+ },
66
+ accounts: {
67
+ propDefinition: [
68
+ common.props.app,
69
+ "accounts",
70
+ ({ adAccountId }) => ({
71
+ adAccountId,
72
+ }),
73
+ ],
74
+ },
75
+ },
76
+ async run({ $ }) {
77
+ const {
78
+ app,
79
+ getDateRangeParam,
80
+ getListParams,
81
+ createReport,
82
+ adAccountId,
83
+ pivot,
84
+ timeGranularity,
85
+ dateRangeStart,
86
+ dateRangeEnd,
87
+ ...arrayProps
88
+ } = this;
89
+
90
+ const response = await createReport({
91
+ $,
92
+ params: {
93
+ q: "analytics",
94
+ pivot,
95
+ timeGranularity,
96
+ dateRange: getDateRangeParam(dateRangeStart, dateRangeEnd),
97
+ ...getListParams(arrayProps),
98
+ },
99
+ });
100
+
101
+ $.export("$summary", `Successfully retrieved analytics information with ${response.elements.length} elements.`);
102
+
103
+ return response.elements;
104
+ },
105
+ };
@@ -0,0 +1,60 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import common from "../common/report.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "linkedin_ads-create-report-by-advertiser-account",
7
+ name: "Create Report By Advertiser Account",
8
+ description: "Sample query using analytics finder that gets analytics for a particular account for date range starting in a given year. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/ads-reporting#sample-request)",
9
+ version: "0.0.4",
10
+ type: "action",
11
+ props: {
12
+ ...common.props,
13
+ startYear: {
14
+ propDefinition: [
15
+ common.props.app,
16
+ "startYear",
17
+ ],
18
+ },
19
+ timeGranularity: {
20
+ propDefinition: [
21
+ common.props.app,
22
+ "timeGranularity",
23
+ ],
24
+ },
25
+ adAccountId: {
26
+ propDefinition: [
27
+ common.props.app,
28
+ "adAccountId",
29
+ ],
30
+ },
31
+ },
32
+ async run({ $ }) {
33
+ const {
34
+ app,
35
+ getDateRangeParam,
36
+ startYear,
37
+ timeGranularity,
38
+ adAccountId,
39
+ getListParam,
40
+ createReport,
41
+ } = this;
42
+
43
+ const response = await createReport({
44
+ $,
45
+ params: {
46
+ "q": "analytics",
47
+ "pivot": "ACCOUNT",
48
+ "dateRange": getDateRangeParam(`${startYear}-01-01`),
49
+ timeGranularity,
50
+ "accounts": getListParam([
51
+ app.getSponsoredAccountUrn(adAccountId),
52
+ ]),
53
+ },
54
+ });
55
+
56
+ $.export("$summary", "Successfully retrieved analytics");
57
+
58
+ return response;
59
+ },
60
+ };
@@ -0,0 +1,69 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import common from "../common/report.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "linkedin_ads-create-report-by-campaign",
7
+ name: "Query Analytics Finder Campaign Sample",
8
+ description: "Sample query using analytics finder that gets analytics for a particular campaign in a date range starting in a given year. [See the docs here](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/ads-reporting#analytics-finder)",
9
+ version: "0.0.4",
10
+ type: "action",
11
+ props: {
12
+ ...common.props,
13
+ startYear: {
14
+ propDefinition: [
15
+ common.props.app,
16
+ "startYear",
17
+ ],
18
+ },
19
+ timeGranularity: {
20
+ propDefinition: [
21
+ common.props.app,
22
+ "timeGranularity",
23
+ ],
24
+ },
25
+ adAccountId: {
26
+ propDefinition: [
27
+ common.props.app,
28
+ "adAccountId",
29
+ ],
30
+ },
31
+ campaignId: {
32
+ propDefinition: [
33
+ common.props.app,
34
+ "campaignId",
35
+ ({ adAccountId }) => ({
36
+ adAccountId,
37
+ }),
38
+ ],
39
+ },
40
+ },
41
+ async run({ $ }) {
42
+ const {
43
+ app,
44
+ getDateRangeParam,
45
+ startYear,
46
+ timeGranularity,
47
+ campaignId,
48
+ getListParam,
49
+ createReport,
50
+ } = this;
51
+
52
+ const response = await createReport({
53
+ $,
54
+ params: {
55
+ "q": "analytics",
56
+ "pivot": "CAMPAIGN",
57
+ "dateRange": getDateRangeParam(`${startYear}-01-01`),
58
+ timeGranularity,
59
+ "campaigns": getListParam([
60
+ app.getSponsoredCampaignUrn(campaignId),
61
+ ]),
62
+ },
63
+ });
64
+
65
+ $.export("$summary", "Successfully retrieved analytics");
66
+
67
+ return response;
68
+ },
69
+ };
@@ -0,0 +1,149 @@
1
+ import { createHash } from "crypto";
2
+ import app from "../../linkedin_ads.app.mjs";
3
+
4
+ export default {
5
+ key: "linkedin_ads-send-conversion-event",
6
+ name: "Send Conversion Event",
7
+ description: "Sends a conversion event to LinkedIn Ads. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/conversions-api?view=li-lms-2024-01&tabs=http#streaming-conversion-events)",
8
+ version: "0.0.3",
9
+ type: "action",
10
+ props: {
11
+ app,
12
+ adAccountId: {
13
+ propDefinition: [
14
+ app,
15
+ "adAccountId",
16
+ ],
17
+ },
18
+ conversionId: {
19
+ propDefinition: [
20
+ app,
21
+ "conversionId",
22
+ ({ adAccountId }) => ({
23
+ adAccountId,
24
+ }),
25
+ ],
26
+ },
27
+ conversionHappenedAt: {
28
+ type: "string",
29
+ label: "Conversion Happened At",
30
+ description: "Epoch timestamp in milliseconds at which the conversion event happened. Note: If your source records conversion timestamp in seconds, please insert 000 at the end to transform it to milliseconds. Eg. `1590739275000`.",
31
+ },
32
+ email: {
33
+ type: "string",
34
+ label: "Email",
35
+ description: "Email address of the contact associated with the conversion event which needs to be in SHA256 format, a HEX encoded string with a maximum length of 64 characters. Eg. `test@example.com`.",
36
+ },
37
+ firstName: {
38
+ type: "string",
39
+ label: "First Name",
40
+ description: "The first name of the contact to match the conversion.",
41
+ },
42
+ lastName: {
43
+ type: "string",
44
+ label: "Last Name",
45
+ description: "The last name of the contact to match the conversion.",
46
+ },
47
+ conversionValueCurrencyCode: {
48
+ type: "string",
49
+ label: "Conversion Value Currency Code",
50
+ description: "The currency code of the conversion value in ISO format. Eg. `USD`.",
51
+ },
52
+ conversionValueAmount: {
53
+ type: "string",
54
+ label: "Conversion Value Amount",
55
+ description: "The value of the conversion in decimal string. If you set this field, you must also set in the **Conversion Value Currency Code** field. Eg. `100.05`.",
56
+ },
57
+ companyName: {
58
+ type: "string",
59
+ label: "Company Name",
60
+ description: "A plain text string representing the company of the contact to match.",
61
+ optional: true,
62
+ },
63
+ title: {
64
+ type: "string",
65
+ label: "Title",
66
+ description: "A plain text string representing the title name of the contact to match. Eg. `Software Engineer`.",
67
+ optional: true,
68
+ },
69
+ countryCode: {
70
+ type: "string",
71
+ label: "Country Code",
72
+ description: "An ISO standardized [two letter country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) representing the country of the contact to match. Eg. `US`.",
73
+ optional: true,
74
+ },
75
+ eventId: {
76
+ type: "string",
77
+ label: "Event ID",
78
+ description: "The unique id generated by advertisers to indicate each event. This field is used for [deduplication](https://learn.microsoft.com/en-us/linkedin/marketing/conversions/deduplication?view=li-lms-2024-01).",
79
+ optional: true,
80
+ },
81
+ },
82
+ methods: {
83
+ emailToSha256(email) {
84
+ return createHash("sha256")
85
+ .update(email)
86
+ .digest("hex");
87
+ },
88
+ sendConversionEvent(args = {}) {
89
+ return this.app._makeRequest({
90
+ debug: true,
91
+ method: "POST",
92
+ path: "/conversionEvents",
93
+ ...args,
94
+ });
95
+ },
96
+ },
97
+ async run({ $ }) {
98
+ const {
99
+ app,
100
+ emailToSha256,
101
+ sendConversionEvent,
102
+ conversionId,
103
+ conversionHappenedAt,
104
+ conversionValueCurrencyCode,
105
+ conversionValueAmount,
106
+ email,
107
+ firstName,
108
+ lastName,
109
+ companyName,
110
+ title,
111
+ countryCode,
112
+ eventId,
113
+ } = this;
114
+
115
+ await sendConversionEvent({
116
+ $,
117
+ data: {
118
+ conversion: app.getConversionUrn(conversionId),
119
+ conversionHappenedAt: Number(conversionHappenedAt),
120
+ conversionValue: {
121
+ currencyCode: conversionValueCurrencyCode,
122
+ amount: conversionValueAmount,
123
+ },
124
+ user: {
125
+ userIds: [
126
+ {
127
+ idType: "SHA256_EMAIL",
128
+ idValue: emailToSha256(email),
129
+ },
130
+ ],
131
+ userInfo: {
132
+ firstName,
133
+ lastName,
134
+ companyName,
135
+ title,
136
+ countryCode,
137
+ },
138
+ },
139
+ eventId,
140
+ },
141
+ });
142
+
143
+ $.export("$summary", "Successfully sent conversion event to LinkedIn Ads");
144
+
145
+ return {
146
+ success: true,
147
+ };
148
+ },
149
+ };
@@ -0,0 +1,54 @@
1
+ function encodeParamKeys(keys = []) {
2
+ return (key, value) => {
3
+ if (!keys.includes(key)) {
4
+ return `${key}=${value}`;
5
+ }
6
+ const [
7
+ firstPart,
8
+ ...otherParts
9
+ ] = value.split(":");
10
+
11
+ if (!firstPart?.startsWith("(")) {
12
+ const encoded = encodeURIComponent(value)
13
+ .replace("(", "%28")
14
+ .replace(")", "%29");
15
+ return `${key}=${encoded}`;
16
+ }
17
+
18
+ return `${key}=${firstPart}:${encodeURIComponent(otherParts.join(":"))}`;
19
+ };
20
+ }
21
+
22
+ function defaultEncodeFn(key, value) {
23
+ return `${key}=${value}`;
24
+ }
25
+
26
+ function encodeFn(key, value) {
27
+ return `${key}=${encodeURIComponent(value)}`;
28
+ }
29
+
30
+ function getParamsSerializer(encodeFn = defaultEncodeFn) {
31
+ return (params) => {
32
+ return Object.entries(params)
33
+ .map(([
34
+ key,
35
+ value,
36
+ ]) => encodeFn(key, value))
37
+ .join("&");
38
+ };
39
+ }
40
+
41
+ function transformResponse(jsonStr) {
42
+ // Regex to target specifically "id" fields, capturing
43
+ // the number to convert it into a string
44
+ // Because the number can be a long number or big integer
45
+ const response = jsonStr.replace(/("id"\s*:\s*)(\d+)/g, "$1\"$2\"");
46
+ return JSON.parse(response);
47
+ }
48
+
49
+ export default {
50
+ encodeParamKeys,
51
+ encodeFn,
52
+ getParamsSerializer,
53
+ transformResponse,
54
+ };
@@ -132,7 +132,6 @@ export default {
132
132
  }) {
133
133
  const count = 20;
134
134
  const { elements } = await this.searchLeadForms({
135
- debug: true,
136
135
  params: {
137
136
  q: "owner",
138
137
  owner: `(sponsoredAccount:${this.getSponsoredAccountUrn(adAccountId)})`,
@@ -192,7 +191,6 @@ export default {
192
191
  leadFormId, ...args
193
192
  } = {}) {
194
193
  return this._makeRequest({
195
- debug: true,
196
194
  path: `/leadForms/${leadFormId}`,
197
195
  ...args,
198
196
  });
@@ -202,7 +200,6 @@ export default {
202
200
  "organizer",
203
201
  ];
204
202
  return this._makeRequest({
205
- debug: true,
206
203
  path: "/events",
207
204
  paramsSerializer: utils.getParamsSerializer(utils.encodeParamKeys(keys)),
208
205
  transformResponse: utils.transformResponse,
@@ -211,7 +208,6 @@ export default {
211
208
  },
212
209
  searchConversions(args = {}) {
213
210
  return this._makeRequest({
214
- debug: true,
215
211
  path: "/conversions",
216
212
  paramsSerializer: utils.getParamsSerializer(utils.encodeFn),
217
213
  ...args,
@@ -224,7 +220,6 @@ export default {
224
220
  "associatedEntity",
225
221
  ];
226
222
  return this._makeRequest({
227
- debug: true,
228
223
  path: "/leadFormResponses",
229
224
  paramsSerializer: utils.getParamsSerializer(utils.encodeParamKeys(keys)),
230
225
  ...args,
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@pipedream/linkedin_ads",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Pipedream LinkedIn Ads Components",
5
5
  "main": "linkedin_ads.app.mjs",
6
6
  "keywords": [
7
7
  "pipedream",
8
8
  "linkedin_ads"
9
9
  ],
10
- "files": [
11
- "dist"
12
- ],
13
10
  "homepage": "https://pipedream.com/apps/linkedin_ads",
14
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
15
12
  "publishConfig": {
16
13
  "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "@pipedream/platform": "^3.0.3"
17
17
  }
18
18
  }
@@ -0,0 +1,62 @@
1
+ import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2
+ import app from "../../linkedin_ads.app.mjs";
3
+
4
+ export default {
5
+ key: "linkedin_ads-new-event-registration-form-response",
6
+ name: "New Event Registration Form Response",
7
+ description: "Emit new event when a fresh response is received on the event registration form. User needs to configure the prop of the specific event. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/events?view=li-lms-2024-01&tabs=http)",
8
+ version: "0.0.3",
9
+ type: "source",
10
+ dedupe: "unique",
11
+ props: {
12
+ app,
13
+ timer: {
14
+ type: "$.interface.timer",
15
+ default: {
16
+ intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
17
+ },
18
+ },
19
+ organizationId: {
20
+ propDefinition: [
21
+ app,
22
+ "organizationId",
23
+ ],
24
+ },
25
+ eventId: {
26
+ propDefinition: [
27
+ app,
28
+ "eventId",
29
+ ({ organizationId }) => ({
30
+ organizationId,
31
+ }),
32
+ ],
33
+ },
34
+ },
35
+ async run() {
36
+ const {
37
+ app,
38
+ organizationId,
39
+ eventId,
40
+ } = this;
41
+
42
+ const { elements } = await app.searchLeadFormResponses({
43
+ params: {
44
+ q: "owner",
45
+ owner: `(organization:${app.getOrganizationUrn(organizationId)})`,
46
+ leadType: "(leadType:EVENT)",
47
+ limitedToTestLeads: false,
48
+ associatedEntity: app.getEventUrn(eventId),
49
+ },
50
+ });
51
+
52
+ elements
53
+ .reverse()
54
+ .forEach((event) => {
55
+ this.$emit(event, {
56
+ id: event.id,
57
+ summary: `New Event Registration: ${event.id}`,
58
+ ts: event.submittedAt,
59
+ });
60
+ });
61
+ },
62
+ };
@@ -0,0 +1,68 @@
1
+ import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2
+ import app from "../../linkedin_ads.app.mjs";
3
+ import sampleEmit from "./test-event.mjs";
4
+
5
+ export default {
6
+ key: "linkedin_ads-new-lead-gen-form-created",
7
+ name: "New Lead Gen Form Created",
8
+ description: "Emit new event when a new lead is captured through a form. [See the documentation](https://learn.microsoft.com/en-us/linkedin/marketing/lead-sync/leadsync?view=li-lms-2023-07&tabs=http#find-lead-form-responses-by-owner)",
9
+ version: "0.0.2",
10
+ type: "source",
11
+ dedupe: "unique",
12
+ props: {
13
+ app,
14
+ timer: {
15
+ type: "$.interface.timer",
16
+ default: {
17
+ intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
18
+ },
19
+ },
20
+ adAccountId: {
21
+ propDefinition: [
22
+ app,
23
+ "adAccountId",
24
+ ],
25
+ },
26
+ leadFormId: {
27
+ propDefinition: [
28
+ app,
29
+ "leadFormId",
30
+ ({ adAccountId }) => ({
31
+ adAccountId,
32
+ }),
33
+ ],
34
+ },
35
+ },
36
+ async run() {
37
+ const {
38
+ app,
39
+ adAccountId,
40
+ leadFormId,
41
+ } = this;
42
+
43
+ const { versionId: leadFormVersionId } = await app.getLeadForm({
44
+ leadFormId,
45
+ });
46
+
47
+ const { elements } = await app.searchLeadFormResponses({
48
+ params: {
49
+ q: "owner",
50
+ owner: `(sponsoredAccount:${app.getSponsoredAccountUrn(adAccountId)})`,
51
+ leadType: "(leadType:SPONSORED)",
52
+ limitedToTestLeads: false,
53
+ versionedLeadGenFormUrn: app.getVersionedLeadGenFormUrn(leadFormId, leadFormVersionId),
54
+ },
55
+ });
56
+
57
+ elements
58
+ .reverse()
59
+ .forEach((event) => {
60
+ this.$emit(event, {
61
+ id: event.id,
62
+ summary: `New Lead Gen: ${event.id}`,
63
+ ts: event.submittedAt,
64
+ });
65
+ });
66
+ },
67
+ sampleEmit,
68
+ };
@@ -0,0 +1,48 @@
1
+ export default {
2
+ "owner": {
3
+ "sponsoredAccount": "urn:li:sponsoredAccount:1232131"
4
+ },
5
+ "submitter": "urn:li:person:0",
6
+ "leadType": "SPONSORED",
7
+ "leadMetadata": {
8
+ "sponsoredLeadMetadata": {
9
+ "campaign": "urn:li:sponsoredCampaign:32131231"
10
+ }
11
+ },
12
+ "versionedLeadGenFormUrn": "urn:li:versionedLeadGenForm:(urn:li:leadGenForm:3213,1)",
13
+ "id": "52dcb737-26f9-4af3-b1fc-935b3e93f838-4",
14
+ "submittedAt": 1706741502694,
15
+ "testLead": true,
16
+ "associatedEntity": {
17
+ "associatedCreative": "urn:li:sponsoredCreative:369799186"
18
+ },
19
+ "formResponse": {
20
+ "consentResponses": [],
21
+ "answers": [
22
+ {
23
+ "answerDetails": {
24
+ "textQuestionAnswer": {
25
+ "answer": "test1@gmail.com"
26
+ }
27
+ },
28
+ "questionId": 20502584796
29
+ },
30
+ {
31
+ "answerDetails": {
32
+ "textQuestionAnswer": {
33
+ "answer": "Test 1"
34
+ }
35
+ },
36
+ "questionId": 20502643516
37
+ },
38
+ {
39
+ "answerDetails": {
40
+ "textQuestionAnswer": {
41
+ "answer": "Test 1"
42
+ }
43
+ },
44
+ "questionId": 20502667260
45
+ }
46
+ ]
47
+ }
48
+ };