Skip to content

Commit 655478b

Browse files
Merge branch 'master' into 21608-google-business-profile
2 parents 6a762e6 + 5d8889d commit 655478b

189 files changed

Lines changed: 4213 additions & 550 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// x-pd-ai: optimized
2+
import app from "../../amplitude.app.mjs";
3+
import { COHORT_ID_TYPES } from "../../common/constants.mjs";
4+
5+
export default {
6+
key: "amplitude-create-cohort",
7+
name: "Create Cohort",
8+
description: "Create a static cohort in Amplitude from an explicit list of user or Amplitude IDs via `POST /api/3/cohorts/upload` (the only REST-documented cohort creation endpoint; behavioral/dynamic cohorts cannot be created via REST). Use **List Cohorts** to find an existing cohort ID if updating. Example: call with `cohortName=\"Power Users Q3\"`, `appId=849238`, `idType=\"BY_USER_ID\"`, `ids=[\"user@example.com\"]`, `owner=\"admin@example.com\"` -> returns `{cohortId: \"abc123\"}`. [See the documentation](https://amplitude.com/docs/apis/analytics/behavioral-cohorts#upload-cohort).",
9+
version: "0.0.1",
10+
type: "action",
11+
annotations: {
12+
readOnlyHint: false,
13+
destructiveHint: true,
14+
openWorldHint: true,
15+
},
16+
props: {
17+
app,
18+
cohortName: {
19+
type: "string",
20+
label: "Name",
21+
description: "Name of the cohort (the `name` field). Example: `Power Users Q3`.",
22+
},
23+
appId: {
24+
type: "integer",
25+
label: "App ID",
26+
description: "The numeric Amplitude project ID that owns the cohort (the `app_id` field). This isn't retrievable through any Amplitude REST API — find it in Amplitude under Settings > Projects, or in the project's Getting Started page. Example: `849238`.",
27+
},
28+
idType: {
29+
type: "string",
30+
label: "ID Type",
31+
description: "The type of identifiers provided in Ids (the `id_type` field). One of `BY_AMP_ID`, `BY_USER_ID`.",
32+
options: COHORT_ID_TYPES,
33+
},
34+
ids: {
35+
type: "string[]",
36+
label: "IDs",
37+
description: "Array of user or Amplitude IDs to include in the cohort (the `ids` field), matching the chosen ID Type. Example: `[\"12345678\",\"87654321\"]`.",
38+
},
39+
owner: {
40+
type: "string",
41+
label: "Owner",
42+
description: "Login email of the cohort owner (the `owner` field). Example: `user@example.com`.",
43+
},
44+
published: {
45+
type: "boolean",
46+
label: "Published",
47+
description: "Whether the cohort is published/shared (the `published` field).",
48+
optional: true,
49+
},
50+
groupName: {
51+
type: "string",
52+
label: "Group Name",
53+
description: "Optional group name for the cohort (the `cg` field).",
54+
optional: true,
55+
},
56+
skipInvalidIds: {
57+
type: "boolean",
58+
label: "Skip Invalid IDs",
59+
description: "When `true`, silently skip IDs that cannot be resolved instead of failing (the `skip_invalid_ids` field).",
60+
optional: true,
61+
},
62+
existingCohortId: {
63+
type: "string",
64+
label: "Existing Cohort ID",
65+
description: "Optional ID of an existing cohort to overwrite instead of creating a new one (the `existing_cohort_id` field). Use **List Cohorts** to find valid cohort IDs.",
66+
optional: true,
67+
},
68+
},
69+
async run({ $ }) {
70+
const response = await this.app.createCohort({
71+
$,
72+
data: {
73+
name: this.cohortName,
74+
app_id: this.appId,
75+
id_type: this.idType,
76+
ids: this.ids,
77+
owner: this.owner,
78+
published: this.published,
79+
cg: this.groupName,
80+
skip_invalid_ids: this.skipInvalidIds,
81+
existing_cohort_id: this.existingCohortId,
82+
},
83+
});
84+
$.export("$summary", `Successfully created cohort "${this.cohortName}"${response.cohortId
85+
? ` with ID ${response.cohortId}`
86+
: ""}`);
87+
return response;
88+
},
89+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// x-pd-ai: optimized
2+
import app from "../../amplitude.app.mjs";
3+
import { COHORT_DOWNLOAD_MAX_MEMBERS } from "../../common/constants.mjs";
4+
import { parseCohortDownload } from "../../common/utils.mjs";
5+
6+
export default {
7+
key: "amplitude-download-cohort-file",
8+
name: "Download Cohort File",
9+
description: "Download a completed cohort export's member list (step 3 of 3: request -> status -> download). Call **Request Cohort Download** then **Get Cohort Download Status** first, and only call this once status is `JOB COMPLETED` — calling it earlier will fail. Returns one record per member (`amplitude_id`/`user_id`, plus any requested user properties) — not the cohort's own metadata (name, size, definition); use **List Cohorts** for that. Example: call with `requestId=\"req_456\"` -> returns `{requestId: \"req_456\", memberCount: 4200, returnedCount: 4200, truncated: false, members: [{amplitude_id: \"123456789\", user_id: \"user@example.com\"}, ...]}`. [See the documentation](https://amplitude.com/docs/apis/analytics/behavioral-cohorts#download-cohort).",
10+
version: "0.0.1",
11+
type: "action",
12+
annotations: {
13+
readOnlyHint: true,
14+
destructiveHint: false,
15+
openWorldHint: true,
16+
},
17+
props: {
18+
app,
19+
requestId: {
20+
propDefinition: [
21+
app,
22+
"requestId",
23+
],
24+
description: "The `request_id` returned by **Request Cohort Download**, after **Get Cohort Download Status** reports `JOB COMPLETED`. Example: `req_456`.",
25+
},
26+
maxMembers: {
27+
type: "integer",
28+
label: "Max Members",
29+
description: `Maximum number of member records to return. Defaults to ${COHORT_DOWNLOAD_MAX_MEMBERS}. The true total is always reported in \`memberCount\`, with \`truncated: true\` if it exceeds this cap.`,
30+
min: 0,
31+
optional: true,
32+
},
33+
},
34+
async run({ $ }) {
35+
const file = await this.app.downloadCohortFile({
36+
$,
37+
requestId: this.requestId,
38+
});
39+
const {
40+
records: members, totalCount, truncated,
41+
} = await parseCohortDownload(file, {
42+
maxRecords: this.maxMembers ?? COHORT_DOWNLOAD_MAX_MEMBERS,
43+
});
44+
$.export("$summary", `Successfully downloaded ${members.length} of ${totalCount} member(s) for request ${this.requestId}${truncated
45+
? " (truncated)"
46+
: ""}`);
47+
return {
48+
requestId: this.requestId,
49+
memberCount: totalCount,
50+
returnedCount: members.length,
51+
truncated,
52+
members,
53+
};
54+
},
55+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// x-pd-ai: optimized
2+
import app from "../../amplitude.app.mjs";
3+
4+
export default {
5+
key: "amplitude-get-cohort-download-status",
6+
name: "Get Cohort Download Status",
7+
description: "Check whether a cohort download job has finished (step 2 of 3: request -> status -> download). Call **Request Cohort Download** first to get a `requestId`. This action polls internally for up to ~35 seconds before returning, since Amplitude's export jobs commonly take 30-60+ seconds regardless of cohort size. If the returned `async_status` is still `JOB INPROGRESS`, call this action again with the same request ID (it may take a few calls) — do not call **Download Cohort File** until `async_status` is `JOB COMPLETED`. Example: call with `requestId=\"req_456\"` -> returns `{request_id: \"req_456\", cohort_id: \"abc123\", async_status: \"JOB COMPLETED\"}`. [See the documentation](https://amplitude.com/docs/apis/analytics/behavioral-cohorts#get-request-status).",
8+
version: "0.0.1",
9+
type: "action",
10+
annotations: {
11+
readOnlyHint: true,
12+
destructiveHint: false,
13+
openWorldHint: true,
14+
},
15+
props: {
16+
app,
17+
requestId: {
18+
propDefinition: [
19+
app,
20+
"requestId",
21+
],
22+
},
23+
},
24+
async run({ $ }) {
25+
const response = await this.app.pollCohortDownloadStatus({
26+
$,
27+
requestId: this.requestId,
28+
});
29+
$.export("$summary", `Cohort download request ${this.requestId} status: ${response.async_status}`);
30+
return response;
31+
},
32+
};
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// x-pd-ai: optimized
2+
import { ConfigurationError } from "@pipedream/platform";
3+
import app from "../../amplitude.app.mjs";
4+
import {
5+
SEGMENTATION_METRICS,
6+
INTERVAL_OPTIONS,
7+
} from "../../common/constants.mjs";
8+
9+
export default {
10+
key: "amplitude-get-event-segmentation",
11+
name: "Get Event Segmentation",
12+
description: "Query event segmentation data (counts, uniques, and other metrics) for one or more events over a date range from the Amplitude Dashboard REST API. Use this to analyze how an event trends over time, optionally broken down by user properties. Example: call with `event={\"event_type\":\"Purchase\"}`, `startDate=\"20240706\"`, `endDate=\"20240805\"`, `metric=\"uniques\"` -> returns `{data: {xValues: [\"2024-07-06\", ...], series: [[42, 51, ...]]}}` (one value per day per requested series). [See the documentation](https://amplitude.com/docs/apis/analytics/dashboard-rest#event-segmentation).",
13+
version: "0.0.1",
14+
type: "action",
15+
annotations: {
16+
readOnlyHint: true,
17+
destructiveHint: false,
18+
openWorldHint: true,
19+
},
20+
props: {
21+
app,
22+
event: {
23+
type: "string",
24+
label: "Event",
25+
description: "A single JSON-encoded event definition (the `e` param). `event_type` is required; `filters` and `group_by` are optional. Use a real event name from your project (e.g. `Purchase`, `Sign Up`), or Amplitude's built-in `_active`/`_new` events to query overall activity. Example: `{\"event_type\":\"_active\"}` (Amplitude's built-in \"any active event\" — do NOT use the literal string \"Any Active Event\", which is Amplitude UI label text, not a valid `event_type` value, and returns a 400).",
26+
},
27+
startDate: {
28+
propDefinition: [
29+
app,
30+
"startDate",
31+
],
32+
},
33+
endDate: {
34+
propDefinition: [
35+
app,
36+
"endDate",
37+
],
38+
},
39+
metric: {
40+
type: "string",
41+
label: "Metric",
42+
description: "Metric to compute (the `m` param). One of: `uniques`, `totals`, `pct_dau`, `average`, `histogram`, `sums`, `value_avg`, `formula`. Defaults to `uniques`.",
43+
options: SEGMENTATION_METRICS,
44+
optional: true,
45+
},
46+
interval: {
47+
type: "integer",
48+
label: "Interval",
49+
description: "Time interval (the `i` param). One of `-300000` (realtime), `-3600000` (hourly), `1` (daily), `7` (weekly), `30` (monthly). Defaults to `1`.",
50+
options: INTERVAL_OPTIONS,
51+
optional: true,
52+
},
53+
segmentDefinitions: {
54+
propDefinition: [
55+
app,
56+
"segmentDefinitions",
57+
],
58+
},
59+
groupBy: {
60+
type: "string",
61+
label: "Group By",
62+
description: "A user or event property name to group results by (the `g` param).",
63+
optional: true,
64+
},
65+
groupBy2: {
66+
type: "string",
67+
label: "Group By 2",
68+
description: "A second property name to group results by (the `g2` param). Only used together with Group By.",
69+
optional: true,
70+
},
71+
secondEvent: {
72+
type: "string",
73+
label: "Second Event",
74+
description: "A second JSON-encoded event definition (the `e2` param) for a derived/comparison metric. Example: `{\"event_type\":\"Purchase\"}`.",
75+
optional: true,
76+
},
77+
limit: {
78+
propDefinition: [
79+
app,
80+
"limit",
81+
],
82+
},
83+
formula: {
84+
type: "string",
85+
label: "Formula",
86+
description: "Custom formula metric expression (the `formula` param). Required if Metric is set to `formula`. Example: `UNIQUES(A)/UNIQUES(B)`.",
87+
optional: true,
88+
},
89+
},
90+
async run({ $ }) {
91+
if (this.metric === "formula" && !this.formula?.trim()) {
92+
throw new ConfigurationError("**Formula** is required when Metric is set to `formula`. Example: `UNIQUES(A)/UNIQUES(B)`.");
93+
}
94+
const response = await this.app.getEventSegmentation({
95+
$,
96+
params: {
97+
e: this.event,
98+
start: this.startDate,
99+
end: this.endDate,
100+
m: this.metric,
101+
i: this.interval,
102+
s: this.segmentDefinitions,
103+
g: this.groupBy,
104+
g2: this.groupBy2,
105+
e2: this.secondEvent,
106+
limit: this.limit,
107+
formula: this.formula,
108+
},
109+
});
110+
$.export("$summary", `Successfully retrieved event segmentation data from ${this.startDate} to ${this.endDate}`);
111+
return response;
112+
},
113+
};

0 commit comments

Comments
 (0)