rettiwt-api 1.1.0 → 1.1.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/.github/workflows/build-docs.yml +27 -0
- package/README.md +3 -1
- package/dist/Test.d.ts +0 -0
- package/dist/Test.js +2 -0
- package/dist/Test.js.map +1 -0
- package/dist/index.d.ts +16 -5
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/models/graphql/Global.d.ts +4 -0
- package/dist/models/graphql/Global.js +13 -0
- package/dist/models/graphql/Global.js.map +1 -0
- package/dist/models/graphql/TweetTypes.d.ts +6 -0
- package/dist/models/graphql/TweetTypes.js +156 -0
- package/dist/models/graphql/TweetTypes.js.map +1 -0
- package/dist/models/graphql/UserTypes.d.ts +3 -0
- package/dist/models/graphql/UserTypes.js +139 -0
- package/dist/models/graphql/UserTypes.js.map +1 -0
- package/dist/queries/RootQuery.d.ts +4 -0
- package/dist/queries/RootQuery.js +70 -0
- package/dist/queries/RootQuery.js.map +1 -0
- package/dist/resolvers/AccountResolver.d.ts +12 -0
- package/dist/resolvers/AccountResolver.js +84 -0
- package/dist/resolvers/AccountResolver.js.map +1 -0
- package/dist/resolvers/ResolverBase.d.ts +5 -0
- package/dist/resolvers/ResolverBase.js +11 -0
- package/dist/resolvers/ResolverBase.js.map +1 -0
- package/dist/resolvers/TweetResolver.d.ts +54 -0
- package/dist/resolvers/TweetResolver.js +332 -0
- package/dist/resolvers/TweetResolver.js.map +1 -0
- package/dist/resolvers/UserResolver.d.ts +38 -0
- package/dist/resolvers/UserResolver.js +253 -0
- package/dist/resolvers/UserResolver.js.map +1 -0
- package/dist/services/AuthService.d.ts +6 -2
- package/dist/services/AuthService.js +4 -3
- package/dist/services/AuthService.js.map +1 -1
- package/dist/services/CacheService.d.ts +12 -7
- package/dist/services/CacheService.js +12 -7
- package/dist/services/CacheService.js.map +1 -1
- package/dist/services/FetcherService.d.ts +32 -12
- package/dist/services/FetcherService.js +45 -14
- package/dist/services/FetcherService.js.map +1 -1
- package/dist/services/accounts/AccountService.d.ts +23 -6
- package/dist/services/accounts/AccountService.js +34 -9
- package/dist/services/accounts/AccountService.js.map +1 -1
- package/dist/services/data/TrendService.d.ts +17 -0
- package/dist/services/data/TrendService.js +116 -0
- package/dist/services/data/TrendService.js.map +1 -0
- package/dist/services/data/TweetService.d.ts +22 -15
- package/dist/services/data/TweetService.js +22 -15
- package/dist/services/data/TweetService.js.map +1 -1
- package/dist/services/data/UserAccountService.d.ts +42 -0
- package/dist/services/data/UserAccountService.js +239 -0
- package/dist/services/data/UserAccountService.js.map +1 -0
- package/dist/services/data/UserService.d.ts +21 -15
- package/dist/services/data/UserService.js +21 -15
- package/dist/services/data/UserService.js.map +1 -1
- package/dist/services/helper/Deserializers.d.ts +19 -0
- package/dist/services/helper/Deserializers.js +115 -0
- package/dist/services/helper/Deserializers.js.map +1 -0
- package/dist/services/helper/Extractors.d.ts +104 -0
- package/dist/services/helper/Extractors.js +432 -0
- package/dist/services/helper/Extractors.js.map +1 -0
- package/dist/services/helper/Urls.d.ts +85 -0
- package/dist/services/helper/Urls.js +130 -0
- package/dist/services/helper/Urls.js.map +1 -0
- package/dist/services/helper/extractors/Trends.d.ts +3 -0
- package/dist/services/helper/extractors/Trends.js +51 -0
- package/dist/services/helper/extractors/Trends.js.map +1 -0
- package/dist/services/helper/urls/Trends.d.ts +7 -0
- package/dist/services/helper/urls/Trends.js +13 -0
- package/dist/services/helper/urls/Trends.js.map +1 -0
- package/dist/types/Authentication.d.ts +27 -2
- package/dist/types/Authentication.js.map +1 -1
- package/dist/types/HTTP.d.ts +3 -1
- package/dist/types/HTTP.js +3 -1
- package/dist/types/HTTP.js.map +1 -1
- package/dist/types/Resolvers.d.ts +6 -1
- package/dist/types/Service.d.ts +30 -0
- package/dist/types/Service.js +19 -0
- package/dist/types/Service.js.map +1 -0
- package/dist/types/Trends.d.ts +50 -0
- package/dist/types/Trends.js +3 -0
- package/dist/types/Trends.js.map +1 -0
- package/dist/types/Tweet.d.ts +40 -0
- package/dist/types/Tweet.js +5 -0
- package/dist/types/Tweet.js.map +1 -0
- package/dist/types/UserAccount.d.ts +19 -0
- package/dist/types/UserAccount.js +4 -0
- package/dist/types/UserAccount.js.map +1 -0
- package/dist/types/data/Errors.d.ts +9 -3
- package/dist/types/data/Errors.js +9 -3
- package/dist/types/data/Errors.js.map +1 -1
- package/dist/types/data/Service.d.ts +19 -5
- package/dist/types/data/Service.js +6 -3
- package/dist/types/data/Service.js.map +1 -1
- package/dist/types/data/Tweet.d.ts +60 -3
- package/dist/types/data/Tweet.js +0 -1
- package/dist/types/data/Tweet.js.map +1 -1
- package/dist/types/data/User.d.ts +20 -1
- package/dist/types/data/User.js +0 -1
- package/dist/types/data/User.js.map +1 -1
- package/dist/types/graphql/Errors.d.ts +15 -0
- package/dist/types/graphql/Errors.js +23 -0
- package/dist/types/graphql/Errors.js.map +1 -0
- package/dist/types/raw/general/Trends.d.ts +324 -0
- package/dist/types/raw/general/Trends.js +3 -0
- package/dist/types/raw/general/Trends.js.map +1 -0
- package/dist/types/raw/user/Tweets.d.ts +2428 -0
- package/dist/types/raw/user/Tweets.js +3 -0
- package/dist/types/raw/user/Tweets.js.map +1 -0
- package/package.json +5 -4
- package/src/index.ts +19 -6
- package/src/services/AuthService.ts +13 -7
- package/src/services/CacheService.ts +12 -7
- package/src/services/FetcherService.ts +62 -21
- package/src/services/accounts/AccountService.ts +38 -12
- package/src/services/data/TweetService.ts +25 -18
- package/src/services/data/UserService.ts +21 -15
- package/src/types/Authentication.ts +27 -2
- package/src/types/HTTP.ts +4 -2
- package/src/types/Resolvers.ts +14 -6
- package/src/types/data/Errors.ts +10 -4
- package/src/types/data/Service.ts +28 -11
- package/src/types/data/Tweet.ts +109 -31
- package/src/types/data/User.ts +47 -17
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tweets.js","sourceRoot":"","sources":["../../../../src/types/raw/user/Tweets.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rettiwt-api",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"description": "An API for fetching data from TwitterAPI, without any rate limits!",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"bugs": {
|
|
22
22
|
"url": "https://github.com/Rishikant181/Rettiwt-API/issues"
|
|
23
23
|
},
|
|
24
|
-
"homepage": "https://github.
|
|
24
|
+
"homepage": "https://rishikant181.github.io/Rettiwt-API/",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"axios": "
|
|
26
|
+
"axios": "1.3.2",
|
|
27
27
|
"cookiejar": "2.1.4",
|
|
28
28
|
"express": "4.18.2",
|
|
29
29
|
"express-graphql": "0.12.0",
|
|
@@ -32,11 +32,12 @@
|
|
|
32
32
|
"node-libcurl": "3.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/cookiejar": "
|
|
35
|
+
"@types/cookiejar": "2.1.2",
|
|
36
36
|
"@types/express": "4.17.13",
|
|
37
37
|
"@types/graphql": "14.5.0",
|
|
38
38
|
"@types/node": "17.0.24",
|
|
39
39
|
"nodemon": "2.0.20",
|
|
40
|
+
"typedoc": "0.23.26",
|
|
40
41
|
"typescript": "4.6.4"
|
|
41
42
|
}
|
|
42
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,8 +5,11 @@ import { TweetService } from "./services/data/TweetService";
|
|
|
5
5
|
import { AccountService } from "./services/accounts/AccountService";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @param cookie The
|
|
8
|
+
* @param cookie The cookie string to use to fetch data
|
|
9
9
|
* @returns The API for fetching user and tweet data
|
|
10
|
+
* @remarks The cookie can be obtained by using {@link AccountService.login} method.
|
|
11
|
+
* To use the {@link AccountService.login} method, create a {@link Rettiwt} instance without passing any cookie string.
|
|
12
|
+
* Then use the {@link AccountService.login} method of {@link AccountService} to get the cookie.
|
|
10
13
|
*/
|
|
11
14
|
export const Rettiwt = (cookie: string = '') => {
|
|
12
15
|
// Creating new auth service instance using the given cookie string
|
|
@@ -20,8 +23,18 @@ export const Rettiwt = (cookie: string = '') => {
|
|
|
20
23
|
};
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
// Exporting
|
|
24
|
-
export
|
|
25
|
-
export
|
|
26
|
-
export
|
|
27
|
-
export
|
|
26
|
+
// Exporting classes
|
|
27
|
+
export * from './services/AuthService';
|
|
28
|
+
export * from './services/CacheService';
|
|
29
|
+
export * from './services/FetcherService';
|
|
30
|
+
export * from './services/accounts/AccountService';
|
|
31
|
+
export * from './services/data/TweetService';
|
|
32
|
+
export * from './services/data/UserService';
|
|
33
|
+
|
|
34
|
+
// Exporting types
|
|
35
|
+
export * from './types/data/Errors';
|
|
36
|
+
export * from './types/data/Service';
|
|
37
|
+
export * from './types/data/Tweet';
|
|
38
|
+
export * from './types/data/User';
|
|
39
|
+
export * from './types/Authentication';
|
|
40
|
+
export * from './types/HTTP';
|
|
@@ -11,13 +11,19 @@ import { GuestCredentials, AuthCredentials } from '../types/Authentication';
|
|
|
11
11
|
import { config } from '../config/env';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Handles authentication of http requests and other authentication related tasks.
|
|
15
|
+
* @internal
|
|
15
16
|
*/
|
|
16
17
|
export class AuthService {
|
|
17
18
|
// MEMBER DATA
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
19
|
+
/** The common bearer token for authentication. */
|
|
20
|
+
private authToken: string;
|
|
21
|
+
|
|
22
|
+
/** The current authentication credentials. */
|
|
23
|
+
private credentials: AuthCredentials;
|
|
24
|
+
|
|
25
|
+
/** Whether instance has been authenticated or not. */
|
|
26
|
+
public isAuthenticated: boolean;
|
|
21
27
|
|
|
22
28
|
// MEMBER METHODS
|
|
23
29
|
constructor(cookie: string = '') {
|
|
@@ -32,7 +38,7 @@ export class AuthService {
|
|
|
32
38
|
* The following regex pattern is used to extract the csrfToken from the cookie string.
|
|
33
39
|
* This is done by matching any string between the characters 'ct0=' and nearest enclosing ';'.
|
|
34
40
|
* (?<=pattern) starts matching after the given pattern.
|
|
35
|
-
* (?=pattern) stops matching just before the pattern
|
|
41
|
+
* (?=pattern) stops matching just before the pattern.
|
|
36
42
|
*/
|
|
37
43
|
this.credentials = { authToken: this.authToken, csrfToken: cookie.match(/(?<=ct0=).+?(?=;)/) + '', cookie: cookie};
|
|
38
44
|
|
|
@@ -46,7 +52,7 @@ export class AuthService {
|
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
/**
|
|
49
|
-
* @returns The guest credentials fetched from twitter
|
|
55
|
+
* @returns The guest credentials fetched from twitter.
|
|
50
56
|
*/
|
|
51
57
|
async getGuestCredentials(): Promise<GuestCredentials> {
|
|
52
58
|
// Getting the guest credentials from twitter
|
|
@@ -59,4 +65,4 @@ export class AuthService {
|
|
|
59
65
|
guestToken: res.data.guest_token
|
|
60
66
|
}));
|
|
61
67
|
}
|
|
62
|
-
}
|
|
68
|
+
}
|
|
@@ -5,9 +5,12 @@ import NodeCache from 'node-cache';
|
|
|
5
5
|
import * as Parsers from './helper/Parser';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Handles reading and writing of data from and to cache.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* This services uses a local node-cache instance to cache data, since the data to be cached has no real purpose outside of the server session.
|
|
11
|
+
* This serivce follows a singleton pattern, where at any point, only a single instance of this class exists.
|
|
12
|
+
* This is done so that all the data is cached in a single instance, which makes sharing of cached data between different endpoints possible.
|
|
13
|
+
* @internal
|
|
11
14
|
*/
|
|
12
15
|
export class CacheService {
|
|
13
16
|
// MEMBER DATA
|
|
@@ -34,9 +37,11 @@ export class CacheService {
|
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @param data The input data to store
|
|
40
|
+
* Stores the input data in the cache.
|
|
41
|
+
*
|
|
42
|
+
* @param data The input data to store.
|
|
43
|
+
* @returns Whether writing to cache was successful or not.
|
|
44
|
+
* @remarks In order to cache data, the data to be cached must have a unique 'id' field.
|
|
40
45
|
*/
|
|
41
46
|
public write(data: any): void {
|
|
42
47
|
// Converting the data to a list of data
|
|
@@ -56,8 +61,8 @@ export class CacheService {
|
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
/**
|
|
59
|
-
* @
|
|
60
|
-
* @
|
|
64
|
+
* @param id The id id of the data to be fetched from cache.
|
|
65
|
+
* @returns The data with the given id.
|
|
61
66
|
*/
|
|
62
67
|
public read(id: string): any {
|
|
63
68
|
// Getting data from cache
|
|
@@ -17,7 +17,7 @@ import * as TweetDeserializers from './helper/deserializers/Tweets';
|
|
|
17
17
|
import { CurlyOptions } from 'node-libcurl/dist/curly';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* The different types of http requests.
|
|
21
21
|
*/
|
|
22
22
|
export enum HttpMethods {
|
|
23
23
|
POST = "POST",
|
|
@@ -25,15 +25,26 @@ export enum HttpMethods {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* Handles all HTTP requests.
|
|
29
|
+
* @internal
|
|
30
|
+
*
|
|
31
|
+
* This serves as the base service from which all other data services derive their behaviour.
|
|
29
32
|
*/
|
|
30
33
|
export class FetcherService {
|
|
31
34
|
// MEMBER DATA
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
+
/** The authentication service instance. */
|
|
36
|
+
private auth: AuthService;
|
|
37
|
+
|
|
38
|
+
/** The caching service instance. */
|
|
39
|
+
private cache: CacheService;
|
|
40
|
+
|
|
41
|
+
/** Whether instance has been authenticated or not. */
|
|
42
|
+
protected isAuthenticated: boolean;
|
|
35
43
|
|
|
36
44
|
// MEMBER METHODS
|
|
45
|
+
/**
|
|
46
|
+
* @param auth The AuthService instance to use for authentication.
|
|
47
|
+
*/
|
|
37
48
|
constructor(auth: AuthService) {
|
|
38
49
|
this.auth = auth;
|
|
39
50
|
this.cache = CacheService.getInstance();
|
|
@@ -41,47 +52,75 @@ export class FetcherService {
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
55
|
+
* The middleware for handling any HTTP error.
|
|
56
|
+
*
|
|
57
|
+
* @param res The response object received.
|
|
58
|
+
* @throws {@link HttpStatus}.
|
|
59
|
+
* @returns The received response, if no HTTP errors are found.
|
|
46
60
|
*/
|
|
47
61
|
private handleHTTPError(res: CurlyResult): CurlyResult {
|
|
62
|
+
/**
|
|
63
|
+
* If the status code is not 200 => the HTTP request was not successful. hence throwing error
|
|
64
|
+
*/
|
|
48
65
|
if (res.statusCode != 200 && res.statusCode in HttpStatus) {
|
|
49
66
|
throw new Error(HttpStatus[res.statusCode])
|
|
50
67
|
}
|
|
51
|
-
|
|
68
|
+
|
|
52
69
|
return res;
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
73
|
+
* Creates an HTTP request according to the given parameters.
|
|
74
|
+
*
|
|
75
|
+
* This method internally uses node-libcurl library to make curl requests to the URL, instead of node-fetch.
|
|
76
|
+
* This has been done since that way it better mimics the HTTP requests made from browser.
|
|
77
|
+
*
|
|
78
|
+
* @param url The url to fetch data from.
|
|
79
|
+
* @param authenticate Whether to authenticate requests or not.
|
|
80
|
+
* @param method The HTTP method (from {@link HttpMethods}) to use.
|
|
81
|
+
* @param data The data to be sent along with the request (for POST request).
|
|
82
|
+
* @returns The {@link CurlyResult} received.
|
|
61
83
|
*/
|
|
62
84
|
protected async request<DataType>(url: string, authenticate: boolean = true, method: HttpMethods = HttpMethods.GET, data?: any): Promise<CurlyResult<DataType>> {
|
|
63
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Creating the request configuration based on the params
|
|
87
|
+
*/
|
|
64
88
|
let config: CurlyOptions = {
|
|
89
|
+
/**
|
|
90
|
+
* If authorization is required, using the authenticated header, using the authentication credentiials.
|
|
91
|
+
* Else, using the guest header, using the guest credentials.
|
|
92
|
+
*/
|
|
65
93
|
httpHeader: authenticate ? Headers.authorizedHeader(await this.auth.getAuthCredentials()) : Headers.guestHeader(await this.auth.getGuestCredentials()),
|
|
94
|
+
/**
|
|
95
|
+
* Disabling SSL peer verification because verification causes Error 404 (only while fetching tweets), likely because peer verification fails.
|
|
96
|
+
*/
|
|
66
97
|
sslVerifyPeer: false,
|
|
67
98
|
};
|
|
68
99
|
|
|
69
|
-
|
|
100
|
+
/**
|
|
101
|
+
* While making requests, if data is to be sent, the JSON data first need to be stringified.
|
|
102
|
+
* After making the request, the response is then passed to HTTP error handling middlware for HTTP error handling.
|
|
103
|
+
*/
|
|
104
|
+
// If POST request is to be made
|
|
70
105
|
if (method == HttpMethods.POST) {
|
|
71
106
|
return await curly.post(url, { ...config, postFields: JSON.stringify(data) }).then(res => this.handleHTTPError(res));
|
|
72
107
|
}
|
|
73
|
-
// If
|
|
108
|
+
// If GET request is to be made
|
|
74
109
|
else {
|
|
75
110
|
return await curly.get(url, config).then(res => this.handleHTTPError(res));
|
|
76
111
|
}
|
|
77
112
|
}
|
|
78
113
|
|
|
79
114
|
/**
|
|
80
|
-
*
|
|
115
|
+
* Caches the extracted data into the {@link CacheService} instance.
|
|
116
|
+
*
|
|
81
117
|
* @param data The extracted data to be cached
|
|
82
118
|
*/
|
|
83
119
|
protected cacheData(data: any): void {
|
|
84
|
-
|
|
120
|
+
/**
|
|
121
|
+
* The extracted data is in raw form.
|
|
122
|
+
* This raw data is deserialized into the respective known types.
|
|
123
|
+
*/
|
|
85
124
|
let users = data.users.map((user: RawUser) => UserDeserializers.toUser(user));
|
|
86
125
|
let tweets = data.tweets.map((tweet: RawTweet) => TweetDeserializers.toTweet(tweet));
|
|
87
126
|
|
|
@@ -91,11 +130,13 @@ export class FetcherService {
|
|
|
91
130
|
}
|
|
92
131
|
|
|
93
132
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
133
|
+
* Fetches the data with the given id from the cache.
|
|
134
|
+
*
|
|
135
|
+
* @param id The id of the data to be read from cache.
|
|
136
|
+
* @returns The data with the given id. If does not exists, returns undefined.
|
|
96
137
|
*/
|
|
97
138
|
protected readData(id: string): any {
|
|
98
139
|
// Reading data from cache
|
|
99
140
|
return this.cache.read(id);
|
|
100
141
|
}
|
|
101
|
-
}
|
|
142
|
+
}
|
|
@@ -12,12 +12,23 @@ import LoginFlows from './LoginFlows';
|
|
|
12
12
|
import { loginHeader } from '../helper/Headers';
|
|
13
13
|
import { Cookie, CookieJar } from 'cookiejar';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Handles all operations related to a user's account, such as loggin in, managing account, etc
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
15
19
|
export class AccountService {
|
|
16
20
|
// MEMBER DATA
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
/** The AuthService instance to use for authentication. */
|
|
22
|
+
private auth: AuthService;
|
|
23
|
+
|
|
24
|
+
/** The current guest credentials to use. */
|
|
25
|
+
private guestCreds: GuestCredentials;
|
|
26
|
+
|
|
27
|
+
/** The cookies received from Twitter after logging in. */
|
|
28
|
+
private cookies: Cookie[];
|
|
29
|
+
|
|
30
|
+
/** The flow token received after execution of current flow. */
|
|
31
|
+
private flowToken: string;
|
|
21
32
|
|
|
22
33
|
// MEMBER METHODS
|
|
23
34
|
constructor() {
|
|
@@ -40,7 +51,8 @@ export class AccountService {
|
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
/**
|
|
43
|
-
*
|
|
54
|
+
* Step 1: Initiates login
|
|
55
|
+
* @internal
|
|
44
56
|
*/
|
|
45
57
|
private async initiateLogin(): Promise<void> {
|
|
46
58
|
// Initiating the login process
|
|
@@ -58,7 +70,8 @@ export class AccountService {
|
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
/**
|
|
61
|
-
*
|
|
73
|
+
* Step 2: Does something
|
|
74
|
+
* @internal
|
|
62
75
|
*/
|
|
63
76
|
private async jsInstrumentationSubtask(): Promise<void> {
|
|
64
77
|
// Executing the flow
|
|
@@ -73,7 +86,8 @@ export class AccountService {
|
|
|
73
86
|
}
|
|
74
87
|
|
|
75
88
|
/**
|
|
76
|
-
*
|
|
89
|
+
* Step 3: Takes the email for login
|
|
90
|
+
* @internal
|
|
77
91
|
*/
|
|
78
92
|
private async enterUserIdentifier(email: string): Promise<void> {
|
|
79
93
|
// Executing the flow
|
|
@@ -88,7 +102,8 @@ export class AccountService {
|
|
|
88
102
|
}
|
|
89
103
|
|
|
90
104
|
/**
|
|
91
|
-
*
|
|
105
|
+
* Step 4: Takes the username for login
|
|
106
|
+
* @internal
|
|
92
107
|
*/
|
|
93
108
|
private async enterAlternateUserIdentifier(userName: string): Promise<void> {
|
|
94
109
|
// Executing the flow
|
|
@@ -103,7 +118,8 @@ export class AccountService {
|
|
|
103
118
|
}
|
|
104
119
|
|
|
105
120
|
/**
|
|
106
|
-
*
|
|
121
|
+
* Step 5: Takes the password for login
|
|
122
|
+
* @internal
|
|
107
123
|
*/
|
|
108
124
|
private async enterPassword(password: string): Promise<void> {
|
|
109
125
|
// Executing the flow
|
|
@@ -118,7 +134,8 @@ export class AccountService {
|
|
|
118
134
|
}
|
|
119
135
|
|
|
120
136
|
/**
|
|
121
|
-
*
|
|
137
|
+
* Step 6: Gets the actual cookies
|
|
138
|
+
* @internal
|
|
122
139
|
*/
|
|
123
140
|
private async accountDuplicationCheck(): Promise<void> {
|
|
124
141
|
// Executing the flow
|
|
@@ -128,7 +145,7 @@ export class AccountService {
|
|
|
128
145
|
postFields: JSON.stringify(LoginFlows.AccountDuplicationCheck.body(this.flowToken))
|
|
129
146
|
});
|
|
130
147
|
|
|
131
|
-
//
|
|
148
|
+
// Getting the cookies from the set-cookie header of the reponse.
|
|
132
149
|
this.cookies = new CookieJar().setCookies(res.headers[0]['Set-Cookie'] as string[]);
|
|
133
150
|
|
|
134
151
|
// Getting the flow token
|
|
@@ -136,13 +153,22 @@ export class AccountService {
|
|
|
136
153
|
}
|
|
137
154
|
|
|
138
155
|
/**
|
|
156
|
+
* Login to Twitter using the given credentials and get back the cookies.
|
|
157
|
+
* @public
|
|
158
|
+
*
|
|
139
159
|
* @param email The email of the account to be logged into
|
|
140
160
|
* @param userName The username associated with the given account
|
|
141
161
|
* @param password The password to the account
|
|
142
162
|
* @returns The cookies for authenticating with the given account
|
|
143
163
|
*/
|
|
144
164
|
public async login(email: string, userName: string, password: string): Promise<string> {
|
|
145
|
-
|
|
165
|
+
/**
|
|
166
|
+
* This works by sending a chain of request that are required for login to twitter.
|
|
167
|
+
* Each method in the chain returns a flow token that must be provied as payload in the next method in the chain.
|
|
168
|
+
* Each such method is called a subtask.
|
|
169
|
+
* Each subtask sets the {@link flowToken} property of the class which is then given in the payload of the next subtask.
|
|
170
|
+
* The final subtask returns the headers which actually contains the cookie in the 'set-cookie' field.
|
|
171
|
+
*/
|
|
146
172
|
await this.initiateLogin();
|
|
147
173
|
await this.jsInstrumentationSubtask();
|
|
148
174
|
await this.enterUserIdentifier(email);
|
|
@@ -27,19 +27,24 @@ import * as TweetDeserializers from '../helper/deserializers/Tweets';
|
|
|
27
27
|
import { toQueryString } from '../helper/Parser';
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Handles fetching of data related to tweets.
|
|
31
|
+
* @public
|
|
31
32
|
*/
|
|
32
33
|
export class TweetService extends FetcherService {
|
|
33
34
|
// MEMBER METHODS
|
|
35
|
+
/**
|
|
36
|
+
* @param auth The AuthService instance to use for authentication.
|
|
37
|
+
*/
|
|
34
38
|
constructor(auth: AuthService) {
|
|
35
39
|
super(auth);
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
/**
|
|
39
|
-
* @
|
|
40
|
-
* @param
|
|
41
|
-
* @param
|
|
42
|
-
* @
|
|
43
|
+
* @param filter The filter be used for searching the tweets.
|
|
44
|
+
* @param count The number of tweets to fetch.
|
|
45
|
+
* @param cursor The cursor to the next batch of tweets. If blank, first batch is fetched.
|
|
46
|
+
* @returns The list of tweets that match the given filter.
|
|
47
|
+
* @remarks count must be >= 1 and <= 100.
|
|
43
48
|
*/
|
|
44
49
|
async getTweets(filter: TweetFilter, count: number, cursor: string): Promise<CursoredData<Tweet>> {
|
|
45
50
|
// If invalid count provided
|
|
@@ -66,8 +71,8 @@ export class TweetService extends FetcherService {
|
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
/**
|
|
69
|
-
* @
|
|
70
|
-
* @
|
|
74
|
+
* @param tweetId The rest id of the target tweet.
|
|
75
|
+
* @returns The details of a single tweet with the given tweet id.
|
|
71
76
|
*/
|
|
72
77
|
async getTweetById(tweetId: string): Promise<Tweet> {
|
|
73
78
|
// Getting data from cache
|
|
@@ -94,10 +99,11 @@ export class TweetService extends FetcherService {
|
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
/**
|
|
97
|
-
* @
|
|
98
|
-
* @param
|
|
99
|
-
* @param
|
|
100
|
-
* @
|
|
102
|
+
* @param tweetId The rest id of the target tweet.
|
|
103
|
+
* @param count The batch size of the list.
|
|
104
|
+
* @param cursor The cursor to the next batch of users. If blank, first batch is fetched.
|
|
105
|
+
* @returns The list of users who liked the given tweet.
|
|
106
|
+
* @remarks count must be >= 10 (when no cursor is provided) and <= 100.
|
|
101
107
|
*/
|
|
102
108
|
async getTweetLikers(tweetId: string, count: number, cursor: string): Promise<CursoredData<User>> {
|
|
103
109
|
// If user is not authenticated, abort
|
|
@@ -129,10 +135,11 @@ export class TweetService extends FetcherService {
|
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
/**
|
|
132
|
-
* @
|
|
133
|
-
* @param
|
|
134
|
-
* @param
|
|
135
|
-
* @
|
|
138
|
+
* @param tweetId The rest id of the target tweet.
|
|
139
|
+
* @param count The batch size of the list.
|
|
140
|
+
* @param cursor The cursor to the next batch of users. If blank, first batch is fetched.
|
|
141
|
+
* @returns The list of users who retweeted the given tweet.
|
|
142
|
+
* @remarks count must be >= 10 (when no cursor is provided) and <= 100.
|
|
136
143
|
*/
|
|
137
144
|
async getTweetRetweeters(tweetId: string, count: number, cursor: string): Promise<CursoredData<User>> {
|
|
138
145
|
// If user is not authenticated, abort
|
|
@@ -167,9 +174,9 @@ export class TweetService extends FetcherService {
|
|
|
167
174
|
* THIS IS DISABLED FOR USE FOR NOW BECAUSE TWITTER DOESN'T HAVE ANY ENDPOINT FOR FETCHING REPLIES.
|
|
168
175
|
* THE DATA THIS RETURNS IS INCONSISTENT!
|
|
169
176
|
*
|
|
170
|
-
* @
|
|
171
|
-
* @param
|
|
172
|
-
* @
|
|
177
|
+
* @param tweetId The rest id of the target tweet.
|
|
178
|
+
* @param cursor The cursor to the next batch of replies. If blank, first batch is fetched.
|
|
179
|
+
* @returns The list of replies to the given tweet.
|
|
173
180
|
*/
|
|
174
181
|
/*
|
|
175
182
|
async getTweetReplies(tweetId: string, cursor: string): Promise<CursoredData<Tweet>> {
|
|
@@ -24,17 +24,20 @@ import * as UserDeserializers from '../helper/deserializers/Users';
|
|
|
24
24
|
import * as TweetDeserializers from '../helper/deserializers/Tweets';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Handles fetching of data related to user account
|
|
28
28
|
*/
|
|
29
29
|
export class UserService extends FetcherService {
|
|
30
30
|
// MEMBER METHODS
|
|
31
|
+
/**
|
|
32
|
+
* @param auth The AuthService instance to use for authentication.
|
|
33
|
+
*/
|
|
31
34
|
constructor(auth: AuthService) {
|
|
32
35
|
super(auth);
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
/**
|
|
36
|
-
* @returns The details of the given user
|
|
37
39
|
* @param screenName The screen name of the target user.
|
|
40
|
+
* @returns The details of the given user.
|
|
38
41
|
*/
|
|
39
42
|
async getUserDetails(screenName: string): Promise<User> {
|
|
40
43
|
// Fetching the raw data
|
|
@@ -53,8 +56,8 @@ export class UserService extends FetcherService {
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
/**
|
|
56
|
-
* @returns The details of the user with given rest id
|
|
57
59
|
* @param restId The screen name of the target user.
|
|
60
|
+
* @returns The details of the user with given rest id.
|
|
58
61
|
*/
|
|
59
62
|
async getUserDetailsById(restId: string): Promise<User> {
|
|
60
63
|
// Getting data from cache
|
|
@@ -81,10 +84,11 @@ export class UserService extends FetcherService {
|
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
/**
|
|
84
|
-
* @
|
|
85
|
-
* @param
|
|
86
|
-
* @param
|
|
87
|
-
* @
|
|
87
|
+
* @param userId The rest id of the target user.
|
|
88
|
+
* @param count The number of following to fetch.
|
|
89
|
+
* @param cursor The cursor to next batch. If blank, first batch is fetched.
|
|
90
|
+
* @returns The list of users followed by the target user.
|
|
91
|
+
* @remarks count must be >= 40 (when no cursor is provided) and <=100.
|
|
88
92
|
*/
|
|
89
93
|
async getUserFollowing(userId: string, count: number, cursor: string): Promise<CursoredData<User>> {
|
|
90
94
|
// If user is not authenticated, abort
|
|
@@ -116,10 +120,11 @@ export class UserService extends FetcherService {
|
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
/**
|
|
119
|
-
* @
|
|
120
|
-
* @param
|
|
121
|
-
* @param
|
|
122
|
-
* @
|
|
123
|
+
* @param userId The rest id of the target user.
|
|
124
|
+
* @param count The number of followers to fetch.
|
|
125
|
+
* @param cursor The cursor to next batch. If blank, first batch is fetched.
|
|
126
|
+
* @returns The list of users following the target user.
|
|
127
|
+
* @remarks count must be >= 40 (when no cursor is provided) and <=100.
|
|
123
128
|
*/
|
|
124
129
|
async getUserFollowers(userId: string, count: number, cursor: string): Promise<CursoredData<User>> {
|
|
125
130
|
// If user is not authenticated, abort
|
|
@@ -151,10 +156,11 @@ export class UserService extends FetcherService {
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
/**
|
|
154
|
-
* @
|
|
155
|
-
* @param
|
|
156
|
-
* @param
|
|
157
|
-
* @
|
|
159
|
+
* @param userId The rest id of the target user.
|
|
160
|
+
* @param count The number of likes to fetch.
|
|
161
|
+
* @param cursor The cursor to next batch. If blank, first batch is fetched.
|
|
162
|
+
* @returns The list of tweets liked by the target user.
|
|
163
|
+
* @remarks count must be >= 40 (when no cursor is provided) and <= 100.
|
|
158
164
|
*/
|
|
159
165
|
async getUserLikes(userId: string, count: number, cursor: string): Promise<CursoredData<Tweet>> {
|
|
160
166
|
// If user is not authenticated, abort
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The guest credentials for guest authentication.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
3
5
|
*/
|
|
4
6
|
export interface GuestCredentials {
|
|
7
|
+
/** The bearer token from twitter.com.
|
|
8
|
+
*
|
|
9
|
+
* @remarks This is a static bearer token from twitter.com.
|
|
10
|
+
*/
|
|
5
11
|
authToken: string,
|
|
12
|
+
/** The guest token.
|
|
13
|
+
*
|
|
14
|
+
* @remarks This is generated from twitter.com by calling GETTING https://api.twitter.com/1.1/guest/activate.json endpoint.
|
|
15
|
+
*/
|
|
6
16
|
guestToken: string
|
|
7
17
|
};
|
|
8
18
|
|
|
9
19
|
/**
|
|
10
|
-
*
|
|
20
|
+
* The credentials for authenticated/logged in users.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
11
23
|
*/
|
|
12
24
|
export interface AuthCredentials {
|
|
25
|
+
/** The bearer token from twitter.com.
|
|
26
|
+
*
|
|
27
|
+
* @remarks This is a static bearer token from twitter.com.
|
|
28
|
+
*/
|
|
13
29
|
authToken: string,
|
|
30
|
+
/** The guest token.
|
|
31
|
+
*
|
|
32
|
+
* @remarks This is generated from twitter.com by calling GETTING https://api.twitter.com/1.1/guest/activate.json endpoint.
|
|
33
|
+
*/
|
|
14
34
|
csrfToken: string,
|
|
35
|
+
/** The cookie of the twitter account, which is used to authenticate against twitter.
|
|
36
|
+
*
|
|
37
|
+
* @remarks The cookie can be obtained/scraped from any one of the outgoing HTTP request headers to twitter.com.
|
|
38
|
+
* It can also be obtained after logging in to twitter, from the 'set-cookie' field of response.
|
|
39
|
+
*/
|
|
15
40
|
cookie: string
|
|
16
41
|
};
|