Skip to content

Commit b56fd49

Browse files
committed
feat: parse user 24h rate limit headers
1 parent fee926d commit b56fd49

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

doc/rate-limiting.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ const manualFullResponse = await client.v1.get<TweetV1TimelineResult>('statuses/
3232
manualFullResponse.data; // TweetV1TimelineResult
3333
// Rate limit information
3434
manualFullResponse.rateLimit; // { limit: number, remaining: number, reset: number }
35+
// Optional daily limits
36+
manualFullResponse.rateLimit.day; // Application 24h limit (if provided)
37+
manualFullResponse.rateLimit.userDay; // User 24h limit (if provided)
3538
```
3639

3740
## Handle errors - Everywhere in this library

src/client-mixins/request-handler.helper.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ export class RequestHandlerHelper<T> {
213213
};
214214
}
215215

216+
if (res.headers['x-user-limit-24hour-limit']) {
217+
rateLimit.userDay = {
218+
limit: Number(res.headers['x-user-limit-24hour-limit']),
219+
remaining: Number(res.headers['x-user-limit-24hour-remaining']),
220+
reset: Number(res.headers['x-user-limit-24hour-reset']),
221+
};
222+
}
223+
216224
if (this.requestData.rateLimitSaver) {
217225
this.requestData.rateLimitSaver(rateLimit);
218226
}

src/types/responses.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export interface SingleTwitterRateLimit {
1414

1515
export interface TwitterRateLimit extends SingleTwitterRateLimit {
1616
day?: SingleTwitterRateLimit;
17+
userDay?: SingleTwitterRateLimit;
1718
}

test/rate-limit.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'mocha';
2+
import { expect } from 'chai';
3+
import { RequestHandlerHelper } from '../src/client-mixins/request-handler.helper';
4+
import type { IncomingMessage } from 'http';
5+
6+
class TestRequestHandlerHelper extends RequestHandlerHelper<any> {
7+
public parse(res: IncomingMessage) {
8+
return this.getRateLimitFromResponse(res);
9+
}
10+
}
11+
12+
describe('Rate limit parsing', () => {
13+
it('includes user 24-hour limits when present', () => {
14+
const helper = new TestRequestHandlerHelper({
15+
url: new URL('https://example.com'),
16+
options: {},
17+
} as any);
18+
19+
const res = {
20+
headers: {
21+
'x-rate-limit-limit': '15',
22+
'x-rate-limit-remaining': '14',
23+
'x-rate-limit-reset': '100',
24+
'x-app-limit-24hour-limit': '5000',
25+
'x-app-limit-24hour-remaining': '4999',
26+
'x-app-limit-24hour-reset': '200',
27+
'x-user-limit-24hour-limit': '1000',
28+
'x-user-limit-24hour-remaining': '999',
29+
'x-user-limit-24hour-reset': '300',
30+
},
31+
} as unknown as IncomingMessage;
32+
33+
const rateLimit = helper.parse(res)!;
34+
expect(rateLimit.limit).to.equal(15);
35+
expect(rateLimit.day).to.deep.equal({ limit: 5000, remaining: 4999, reset: 200 });
36+
expect(rateLimit.userDay).to.deep.equal({ limit: 1000, remaining: 999, reset: 300 });
37+
});
38+
});
39+

0 commit comments

Comments
 (0)