Skip to content

Commit 4de31ad

Browse files
authored
fix 503 error from opencollective (#4214)
* use api key for opencollective * remove from testing action * add OPENCOLLECTIVE_API_KEY * add comments * make graphqlPageSize smaller * optimize transaction querying * remove api key
1 parent 3995e99 commit 4de31ad

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
uses: JamesIves/[email protected]
4343
with:
4444
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
OPENCOLLECTIVE_API_KEY: ${{ secrets.OPENCOLLECTIVE_API_KEY }}
4546
BRANCH: gh-pages
4647
FOLDER: dist
4748
CLEAN: true

src/utilities/fetch-supporters.js

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,19 @@ const asyncWriteFile = promisify(fs.writeFile);
99

1010
const REQUIRED_KEYS = ['totalDonations', 'slug', 'name'];
1111
const filename = '_supporters.json';
12-
const absoluteFilename = path.resolve(__dirname, '..', 'components', 'Support', filename);
12+
const absoluteFilename = path.resolve(
13+
__dirname,
14+
'..',
15+
'components',
16+
'Support',
17+
filename
18+
);
1319

14-
const graphqlEndpoint = 'https://api.opencollective.com/graphql/v2';
20+
const graphqlEndpoint =
21+
'https://api.opencollective.com/graphql/v2';
22+
23+
// https://github.com/opencollective/opencollective-api/blob/master/server/graphql/v2/query/TransactionsQuery.ts#L81
24+
const graphqlPageSize = 1000;
1525

1626
const membersGraphqlQuery = `query account($limit: Int, $offset: Int) {
1727
account(slug: "webpack") {
@@ -32,10 +42,12 @@ const membersGraphqlQuery = `query account($limit: Int, $offset: Int) {
3242
}
3343
}`;
3444

35-
const transactionsGraphqlQuery = `query account($limit: Int, $offset: Int) {
36-
account(slug: "webpack") {
37-
transactions(limit: $limit, offset: $offset, includeIncognitoTransactions: false) {
38-
nodes {
45+
// only query transactions in last year
46+
const transactionsGraphqlQuery = `query transactions($dateFrom: ISODateTime, $limit: Int, $offset: Int) {
47+
transactions(account: {
48+
slug: "webpack"
49+
}, dateFrom: $dateFrom, limit: $limit, offset: $offset, includeIncognitoTransactions: false) {
50+
nodes {
3951
amountInHostCurrency {
4052
value
4153
}
@@ -47,28 +59,34 @@ const transactionsGraphqlQuery = `query account($limit: Int, $offset: Int) {
4759
}
4860
createdAt
4961
}
50-
}
5162
}
5263
}`;
5364

54-
const graphqlPageSize = 5000;
55-
56-
const nodeToSupporter = node => ({
65+
const nodeToSupporter = (node) => ({
5766
name: node.account.name,
5867
slug: node.account.slug,
5968
website: node.account.website,
6069
avatar: node.account.imageUrl,
6170
firstDonation: node.createdAt,
6271
totalDonations: node.totalDonations.value * 100,
63-
monthlyDonations: 0
72+
monthlyDonations: 0,
6473
});
6574

6675
const getAllNodes = async (graphqlQuery, getNodes) => {
6776
const requestOptions = {
6877
method: 'POST',
6978
uri: graphqlEndpoint,
70-
body: { query: graphqlQuery, variables: { limit: graphqlPageSize, offset: 0 } },
71-
json: true
79+
body: {
80+
query: graphqlQuery,
81+
variables: {
82+
limit: graphqlPageSize,
83+
offset: 0,
84+
dateFrom: new Date(
85+
new Date().setFullYear(new Date().getFullYear() - 1)
86+
).toISOString(), // data from last year
87+
},
88+
},
89+
json: true,
7290
};
7391

7492
let allNodes = [];
@@ -82,15 +100,22 @@ const getAllNodes = async (graphqlQuery, getNodes) => {
82100
requestOptions.body.variables.offset += graphqlPageSize;
83101
if (nodes.length < graphqlPageSize) {
84102
return allNodes;
103+
} else {
104+
// sleep for a while
105+
await new Promise((resolve) => setTimeout(resolve, 100));
85106
}
86107
}
87108
};
88109

89-
const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
90110

91111
(async () => {
92-
const members = await getAllNodes(membersGraphqlQuery, data => data.account.members.nodes);
93-
let supporters = members.map(nodeToSupporter).sort((a, b) => b.totalDonations - a.totalDonations);
112+
const members = await getAllNodes(
113+
membersGraphqlQuery,
114+
(data) => data.account.members.nodes
115+
);
116+
let supporters = members
117+
.map(nodeToSupporter)
118+
.sort((a, b) => b.totalDonations - a.totalDonations);
94119

95120
// Deduplicating supporters with multiple orders
96121
supporters = uniqBy(supporters, 'slug');
@@ -99,37 +124,43 @@ const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
99124
for (const supporter of supporters) {
100125
for (const key of REQUIRED_KEYS) {
101126
if (!supporter || typeof supporter !== 'object') {
102-
throw new Error(`Supporters: ${JSON.stringify(supporter)} is not an object.`);
127+
throw new Error(
128+
`Supporters: ${JSON.stringify(supporter)} is not an object.`
129+
);
103130
}
104131
if (!(key in supporter)) {
105-
throw new Error(`Supporters: ${JSON.stringify(supporter)} doesn't include ${key}.`);
132+
throw new Error(
133+
`Supporters: ${JSON.stringify(supporter)} doesn't include ${key}.`
134+
);
106135
}
107136
}
108137
supportersBySlug.set(supporter.slug, supporter);
109138
}
110139

111140
// Calculate monthly amount from transactions
112-
const transactions = await getAllNodes(transactionsGraphqlQuery, data => data.account.transactions.nodes);
141+
const transactions = await getAllNodes(
142+
transactionsGraphqlQuery,
143+
(data) => data.transactions.nodes
144+
);
113145
for (const transaction of transactions) {
114146
if (!transaction.amountInHostCurrency) continue;
115147
const amount = transaction.amountInHostCurrency.value;
116148
if (!amount || amount <= 0) continue;
117-
const date = +new Date(transaction.createdAt);
118-
if (date < oneYearAgo) continue;
119149
const supporter = supportersBySlug.get(transaction.fromAccount.slug);
120150
if (!supporter) continue;
121-
supporter.monthlyDonations += amount * 100 / 12;
151+
supporter.monthlyDonations += (amount * 100) / 12;
122152
}
123153

124154
for (const supporter of supporters) {
125155
supporter.monthlyDonations = Math.round(supporter.monthlyDonations);
126156
}
127157

128158
// Write the file
129-
return asyncWriteFile(absoluteFilename, JSON.stringify(supporters, null, 2)).then(() =>
130-
console.log(`Fetched 1 file: ${filename}`)
131-
);
132-
})().catch(error => {
159+
return asyncWriteFile(
160+
absoluteFilename,
161+
JSON.stringify(supporters, null, 2)
162+
).then(() => console.log(`Fetched 1 file: ${filename}`));
163+
})().catch((error) => {
133164
console.error('utilities/fetch-supporters:', error);
134165
process.exitCode = 1;
135166
});

0 commit comments

Comments
 (0)