Skip to content

Commit d876bb2

Browse files
committed
[Components] plaid - new components
1 parent b36acd5 commit d876bb2

File tree

18 files changed

+911
-28
lines changed

18 files changed

+911
-28
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import app from "../../plaid.app.mjs";
2+
3+
export default {
4+
key: "plaid-create-access-token",
5+
name: "Create Access Token",
6+
description: "Exchange a Link `public_token` for an API `access_token`. [See the documentation](https://plaid.com/docs/api/items/#itempublic_tokenexchange).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
publicToken: {
12+
propDefinition: [
13+
app,
14+
"publicToken",
15+
],
16+
},
17+
},
18+
async run({ $ }) {
19+
const {
20+
app,
21+
publicToken,
22+
} = this;
23+
24+
const response = await app.exchangePublicToken({
25+
public_token: publicToken,
26+
});
27+
28+
$.export("$summary", "Successfully created access token for public token");
29+
30+
return response;
31+
},
32+
};
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import app from "../../plaid.app.mjs";
2+
import institutions from "../../common/sandbox-institutions.mjs";
3+
4+
export default {
5+
key: "plaid-create-sandbox-public-token",
6+
name: "Create Sandbox Public Token",
7+
description: "Creates a valid `public_token` for an arbitrary institution ID, initial products, and test credentials. [See the documentation](https://plaid.com/docs/api/sandbox/#sandboxpublic_tokencreate).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
app,
12+
institutionId: {
13+
type: "string",
14+
label: "Institution ID",
15+
description: "The ID of the institution the Item will be associated with",
16+
options: Object.values(institutions),
17+
},
18+
initialProducts: {
19+
type: "string[]",
20+
label: "Initial Products",
21+
description: "The products to initially pull for the Item. May be any products that the specified institution supports.",
22+
options: [
23+
"assets",
24+
"auth",
25+
"balance",
26+
"employment",
27+
"identity",
28+
"income_verification",
29+
"identity_verification",
30+
"investments",
31+
"liabilities",
32+
"payment_initiation",
33+
"standing_orders",
34+
"statements",
35+
"transactions",
36+
"transfer",
37+
],
38+
},
39+
webhookUrl: {
40+
type: "string",
41+
label: "Webhook URL",
42+
description: "The URL to which Plaid should send webhook notifications. You must configure at least one webhook to enable webhooks.",
43+
optional: true,
44+
},
45+
overrideUsername: {
46+
type: "string",
47+
label: "Override Username",
48+
description: "Test username to use for the creation of the Sandbox Item. Default is 'user_good'.",
49+
optional: true,
50+
},
51+
overridePassword: {
52+
type: "string",
53+
label: "Override Password",
54+
description: "Test password to use for the creation of the Sandbox Item. Default is 'pass_good'.",
55+
optional: true,
56+
},
57+
userToken: {
58+
type: "string",
59+
label: "User Token",
60+
description: "The user token associated with the User data is being requested for.",
61+
optional: true,
62+
},
63+
},
64+
async run({ $ }) {
65+
const {
66+
app,
67+
institutionId,
68+
initialProducts,
69+
webhookUrl,
70+
overrideUsername,
71+
overridePassword,
72+
userToken,
73+
} = this;
74+
75+
const options = {};
76+
77+
if (webhookUrl) {
78+
options.webhook = webhookUrl;
79+
}
80+
81+
if (overrideUsername || overridePassword) {
82+
options.override_username = overrideUsername;
83+
options.override_password = overridePassword;
84+
}
85+
86+
const response = await app.createSandboxPublicToken({
87+
institution_id: institutionId,
88+
initial_products: initialProducts,
89+
...(Object.keys(options).length > 0 && {
90+
options,
91+
}),
92+
...(userToken && {
93+
user_token: userToken,
94+
}),
95+
});
96+
97+
$.export("$summary", `Successfully created sandbox public token for institution ${institutionId}`);
98+
99+
return response;
100+
},
101+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import app from "../../plaid.app.mjs";
2+
3+
export default {
4+
key: "plaid-get-real-time-balance",
5+
name: "Get Real-Time Balance",
6+
description: "Get the real-time balance for each of an Item's accounts. [See the documentation](https://plaid.com/docs/api/products/balance/#accountsbalanceget).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
accessToken: {
12+
propDefinition: [
13+
app,
14+
"accessToken",
15+
],
16+
},
17+
accountIds: {
18+
type: "string[]",
19+
label: "Account IDs",
20+
description: "The specific account IDs to filter by. If not provided, all accounts will be returned.",
21+
propDefinition: [
22+
app,
23+
"accountId",
24+
({ accessToken }) => ({
25+
accessToken,
26+
}),
27+
],
28+
},
29+
},
30+
async run({ $ }) {
31+
const {
32+
app,
33+
accessToken,
34+
accountIds,
35+
} = this;
36+
37+
const response = await app.getAccountsBalance({
38+
access_token: accessToken,
39+
options: {
40+
account_ids: accountIds,
41+
},
42+
});
43+
44+
$.export("$summary", "Successfully fetched account balances");
45+
return response;
46+
},
47+
};
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import app from "../../plaid.app.mjs";
2+
3+
export default {
4+
key: "plaid-get-transactions",
5+
name: "Get Transactions",
6+
description: "Retrieves user-authorized transaction data for a specified date range. [See the documentation](https://plaid.com/docs/api/products/transactions/#transactionsget)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
accessToken: {
12+
propDefinition: [
13+
app,
14+
"accessToken",
15+
],
16+
},
17+
startDate: {
18+
propDefinition: [
19+
app,
20+
"startDate",
21+
],
22+
},
23+
endDate: {
24+
propDefinition: [
25+
app,
26+
"endDate",
27+
],
28+
},
29+
accountIds: {
30+
type: "string[]",
31+
label: "Account IDs",
32+
description: "A list of `account_ids` to retrieve for the Item. Note: An error will be returned if a provided `account_id` is not associated with the Item.",
33+
propDefinition: [
34+
app,
35+
"accountId",
36+
({ accessToken }) => ({
37+
accessToken,
38+
}),
39+
],
40+
},
41+
includeOriginalDescription: {
42+
type: "boolean",
43+
label: "Include Original Description",
44+
description: "Include the raw unparsed transaction description from the financial institution.",
45+
default: false,
46+
optional: true,
47+
},
48+
daysRequested: {
49+
type: "integer",
50+
label: "Days Requested",
51+
description: "Number of days of transaction history to request from the financial institution. Only applies when Transactions product hasn't been initialized. Min: 1, Max: 730, Default: 90.",
52+
min: 1,
53+
max: 730,
54+
optional: true,
55+
},
56+
},
57+
async run({ $ }) {
58+
const {
59+
app,
60+
accessToken,
61+
startDate,
62+
endDate,
63+
accountIds,
64+
includeOriginalDescription,
65+
daysRequested,
66+
} = this;
67+
68+
const options = {};
69+
70+
if (accountIds?.length) {
71+
options.account_ids = accountIds;
72+
}
73+
74+
if (includeOriginalDescription !== undefined) {
75+
options.include_original_description = includeOriginalDescription;
76+
}
77+
78+
if (daysRequested) {
79+
options.days_requested = daysRequested;
80+
}
81+
82+
const transactions = await app.paginate({
83+
resourcesFn: app.getTransactions,
84+
resourcesFnArgs: {
85+
access_token: accessToken,
86+
start_date: startDate,
87+
end_date: endDate,
88+
...(Object.keys(options).length > 0 && {
89+
options,
90+
}),
91+
},
92+
resourceName: "transactions",
93+
});
94+
95+
const transactionCount = transactions?.length || 0;
96+
$.export("$summary", `Successfully retrieved ${transactionCount} transactions from ${startDate} to ${endDate}`);
97+
98+
return transactions;
99+
},
100+
};

components/plaid/common/constants.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const DEFAULT_LIMIT = 100;
2+
const DEFAULT_MAX = 600;
3+
4+
export default {
5+
DEFAULT_LIMIT,
6+
DEFAULT_MAX,
7+
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
export default {
2+
INS_109508: {
3+
label: "First Platypus Bank (non-OAuth bank)",
4+
value: "ins_109508",
5+
},
6+
INS_109509: {
7+
label: "First Gingham Credit Union (non-OAuth bank)",
8+
value: "ins_109509",
9+
},
10+
INS_109510: {
11+
label: "Tattersall Federal Credit Union (non-OAuth bank)",
12+
value: "ins_109510",
13+
},
14+
INS_109511: {
15+
label: "Tartan Bank (non-OAuth bank)",
16+
value: "ins_109511",
17+
},
18+
INS_109512: {
19+
label: "Houndstooth Bank (for Instant Match and Automated Micro-deposit testing)",
20+
value: "ins_109512",
21+
},
22+
INS_43: {
23+
label: "Tartan-Dominion Bank of Canada (Canadian bank)",
24+
value: "ins_43",
25+
},
26+
INS_116834: {
27+
label: "Flexible Platypus Open Banking (UK Bank)",
28+
value: "ins_116834",
29+
},
30+
INS_117650: {
31+
label: "Royal Bank of Plaid (UK Bank)",
32+
value: "ins_117650",
33+
},
34+
INS_127287: {
35+
label: "Platypus OAuth Bank (for OAuth testing)",
36+
value: "ins_127287",
37+
},
38+
INS_132241: {
39+
label: "First Platypus OAuth App2App Bank (for App-to-App OAuth testing)",
40+
value: "ins_132241",
41+
},
42+
INS_117181: {
43+
label: "Flexible Platypus Open Banking (for OAuth QR code authentication testing)",
44+
value: "ins_117181",
45+
},
46+
INS_135858: {
47+
label: "Windowpane Bank (for Instant Micro-deposit testing)",
48+
value: "ins_135858",
49+
},
50+
INS_132363: {
51+
label: "Unhealthy Platypus Bank - Degraded",
52+
value: "ins_132363",
53+
},
54+
INS_132361: {
55+
label: "Unhealthy Platypus Bank - Down",
56+
value: "ins_132361",
57+
},
58+
INS_133402: {
59+
label: "Unsupported Platypus Bank - Institution Not Supported",
60+
value: "ins_133402",
61+
},
62+
INS_133502: {
63+
label: "Platypus Bank RUX Auth (formerly for testing legacy RUX flows)",
64+
value: "ins_133502",
65+
},
66+
INS_133503: {
67+
label: "Platypus Bank RUX Match (formerly for testing legacy RUX flows)",
68+
value: "ins_133503",
69+
},
70+
};

components/plaid/common/utils.mjs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
async function iterate(iterations) {
2+
const items = [];
3+
for await (const item of iterations) {
4+
items.push(item);
5+
}
6+
return items;
7+
}
8+
9+
function getNestedProperty(obj, propertyString) {
10+
const properties = propertyString.split(".");
11+
return properties.reduce((prev, curr) => prev?.[curr], obj);
12+
}
13+
14+
export default {
15+
iterate,
16+
getNestedProperty,
17+
};

components/plaid/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/plaid",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Pipedream plaid Components",
55
"main": "plaid.app.mjs",
66
"keywords": [
@@ -13,6 +13,7 @@
1313
"access": "public"
1414
},
1515
"dependencies": {
16-
"@pipedream/platform": "^3.0.0"
16+
"@pipedream/platform": "^3.0.3",
17+
"plaid": "^33.0.0"
1718
}
1819
}

0 commit comments

Comments
 (0)