@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.
- package/actions/common/report.mjs +62 -0
- package/actions/create-report/create-report.mjs +105 -0
- package/actions/create-report-by-advertiser-account/create-report-by-advertiser-account.mjs +60 -0
- package/actions/create-report-by-campaign/create-report-by-campaign.mjs +69 -0
- package/actions/send-conversion-event/send-conversion-event.mjs +149 -0
- package/common/utils.mjs +54 -0
- package/linkedin_ads.app.mjs +0 -5
- package/package.json +4 -4
- package/sources/new-event-registration-form-response/new-event-registration-form-response.mjs +62 -0
- package/sources/new-lead-gen-form-created/new-lead-gen-form-created.mjs +68 -0
- package/sources/new-lead-gen-form-created/test-event.mjs +48 -0
|
@@ -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
|
+
};
|
package/common/utils.mjs
ADDED
|
@@ -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
|
+
};
|
package/linkedin_ads.app.mjs
CHANGED
|
@@ -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.
|
|
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
|
+
};
|