@the-convocation/twitter-scraper 0.0.8 → 0.1.0
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/dist/api.js +76 -76
- package/dist/auth.js +118 -118
- package/dist/profile.js +102 -102
- package/dist/scraper.js +152 -152
- package/dist/search.js +83 -83
- package/dist/timeline-async.js +58 -58
- package/dist/timeline.js +227 -227
- package/dist/trends.js +45 -45
- package/dist/tweets.js +58 -58
- package/dist/types/api.d.ts +15 -15
- package/dist/types/auth.d.ts +54 -54
- package/dist/types/profile.d.ts +66 -66
- package/dist/types/scraper.d.ts +101 -101
- package/dist/types/search.d.ts +18 -18
- package/dist/types/timeline-async.d.ts +14 -14
- package/dist/types/timeline.d.ts +153 -153
- package/dist/types/trends.d.ts +2 -2
- package/dist/types/tweets.d.ts +51 -51
- package/package.json +1 -1
- package/.commitlintrc +0 -5
- package/.eslintcache +0 -1
- package/.eslintrc.js +0 -24
- package/.gitattributes +0 -78
- package/.prettierignore +0 -2
- package/.prettierrc +0 -5
package/dist/scraper.js
CHANGED
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { bearerToken, bearerToken2 } from './api';
|
|
11
|
-
import { TwitterGuestAuth } from './auth';
|
|
12
|
-
import { getProfile, getUserIdByScreenName } from './profile';
|
|
13
|
-
import { fetchSearchProfiles, fetchSearchTweets, SearchMode, searchProfiles, searchTweets, } from './search';
|
|
14
|
-
import { getTrends } from './trends';
|
|
15
|
-
import { getTweet, getTweets } from './tweets';
|
|
16
|
-
/**
|
|
17
|
-
* An interface to Twitter's undocumented API.
|
|
18
|
-
* Reusing Scraper objects is recommended to minimize the time spent authenticating unnecessarily.
|
|
19
|
-
*/
|
|
20
|
-
export class Scraper {
|
|
21
|
-
/**
|
|
22
|
-
* Creates a new Scraper object. Scrapers maintain their own guest tokens for Twitter's internal API.
|
|
23
|
-
* Reusing Scraper objects is recommended to minimize the time spent authenticating unnecessarily.
|
|
24
|
-
*/
|
|
25
|
-
constructor() {
|
|
26
|
-
this.auth = new TwitterGuestAuth(bearerToken);
|
|
27
|
-
this.authTrends = new TwitterGuestAuth(bearerToken2);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Fetches a Twitter profile.
|
|
31
|
-
* @param username The Twitter username of the profile to fetch, without an `@` at the beginning.
|
|
32
|
-
* @returns The requested profile.
|
|
33
|
-
*/
|
|
34
|
-
getProfile(username) {
|
|
35
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
const res = yield getProfile(username, this.auth);
|
|
37
|
-
return this.handleResponse(res);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Fetches the user ID corresponding to the provided screen name.
|
|
42
|
-
* @param screenName The Twitter screen name of the profile to fetch.
|
|
43
|
-
* @returns The ID of the corresponding account.
|
|
44
|
-
*/
|
|
45
|
-
getUserIdByScreenName(screenName) {
|
|
46
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
-
const res = yield getUserIdByScreenName(screenName, this.auth);
|
|
48
|
-
return this.handleResponse(res);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Fetches tweets from Twitter.
|
|
53
|
-
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
54
|
-
* @param maxTweets The maximum number of tweets to return.
|
|
55
|
-
* @param includeReplies Whether or not replies should be included in the response.
|
|
56
|
-
* @param searchMode The category filter to apply to the search. Defaults to `Top`.
|
|
57
|
-
* @returns An async generator of tweets matching the provided filters.
|
|
58
|
-
*/
|
|
59
|
-
searchTweets(query, maxTweets, includeReplies, searchMode = SearchMode.Top) {
|
|
60
|
-
return searchTweets(query, maxTweets, includeReplies, searchMode, this.auth);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Fetches profiles from Twitter.
|
|
64
|
-
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
65
|
-
* @param maxProfiles The maximum number of profiles to return.
|
|
66
|
-
* @returns An async generator of tweets matching the provided filters.
|
|
67
|
-
*/
|
|
68
|
-
searchProfiles(query, maxProfiles) {
|
|
69
|
-
return searchProfiles(query, maxProfiles, this.auth);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Fetches tweets from Twitter.
|
|
73
|
-
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
74
|
-
* @param maxTweets The maximum number of tweets to return.
|
|
75
|
-
* @param includeReplies Whether or not replies should be included in the response.
|
|
76
|
-
* @param searchMode The category filter to apply to the search. Defaults to `Top`.
|
|
77
|
-
* @param cursor The search cursor, which can be passed into further requests for more results.
|
|
78
|
-
* @returns A page of results, containing a cursor that can be used in further requests.
|
|
79
|
-
*/
|
|
80
|
-
fetchSearchTweets(query, maxTweets, includeReplies, searchMode, cursor) {
|
|
81
|
-
return fetchSearchTweets(query, maxTweets, includeReplies, searchMode, this.auth, cursor);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Fetches profiles from Twitter.
|
|
85
|
-
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
86
|
-
* @param maxProfiles The maximum number of profiles to return.
|
|
87
|
-
* @param cursor The search cursor, which can be passed into further requests for more results.
|
|
88
|
-
* @returns A page of results, containing a cursor that can be used in further requests.
|
|
89
|
-
*/
|
|
90
|
-
fetchSearchProfiles(query, maxProfiles, cursor) {
|
|
91
|
-
return fetchSearchProfiles(query, maxProfiles, this.auth, cursor);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Fetches the current trends from Twitter.
|
|
95
|
-
* @returns The current list of trends.
|
|
96
|
-
*/
|
|
97
|
-
getTrends() {
|
|
98
|
-
return getTrends(this.authTrends);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Fetches tweets from a Twitter user.
|
|
102
|
-
* @param user The user whose tweets should be returned.
|
|
103
|
-
* @param maxTweets The maximum number of tweets to return.
|
|
104
|
-
* @param includeReplies Whether or not to include tweet replies.
|
|
105
|
-
* @returns An async generator of tweets from the provided user.
|
|
106
|
-
*/
|
|
107
|
-
getTweets(user, maxTweets, includeReplies) {
|
|
108
|
-
return getTweets(user, maxTweets, includeReplies, this.auth);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Fetches a single tweet.
|
|
112
|
-
* @param id The ID of the tweet to fetch.
|
|
113
|
-
* @param includeReplies Whether or not to include tweet replies.
|
|
114
|
-
* @returns The request tweet, or `null` if it couldn't be fetched.
|
|
115
|
-
*/
|
|
116
|
-
getTweet(id, includeReplies) {
|
|
117
|
-
return getTweet(id, includeReplies, this.auth);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Returns if the scraper has a guest token. The token may not be valid.
|
|
121
|
-
* @returns `true` if the scraper has a guest token; otherwise `false`.
|
|
122
|
-
*/
|
|
123
|
-
hasGuestToken() {
|
|
124
|
-
return this.auth.hasToken() || this.authTrends.hasToken();
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Sets the optional cookie to be used in requests.
|
|
128
|
-
* @param cookie The cookie to be used in requests.
|
|
129
|
-
* @returns This scraper instance.
|
|
130
|
-
*/
|
|
131
|
-
withCookie(cookie) {
|
|
132
|
-
this.auth.useCookie(cookie);
|
|
133
|
-
this.authTrends.useCookie(cookie);
|
|
134
|
-
return this;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Sets the optional CSRF token to be used in requests.
|
|
138
|
-
* @param token The CSRF token to be used in requests.
|
|
139
|
-
* @returns This scraper instance.
|
|
140
|
-
*/
|
|
141
|
-
withXCsrfToken(token) {
|
|
142
|
-
this.auth.useCsrfToken(token);
|
|
143
|
-
this.authTrends.useCsrfToken(token);
|
|
144
|
-
return this;
|
|
145
|
-
}
|
|
146
|
-
handleResponse(res) {
|
|
147
|
-
if (!res.success) {
|
|
148
|
-
throw res.err;
|
|
149
|
-
}
|
|
150
|
-
return res.value;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { bearerToken, bearerToken2 } from './api';
|
|
11
|
+
import { TwitterGuestAuth } from './auth';
|
|
12
|
+
import { getProfile, getUserIdByScreenName } from './profile';
|
|
13
|
+
import { fetchSearchProfiles, fetchSearchTweets, SearchMode, searchProfiles, searchTweets, } from './search';
|
|
14
|
+
import { getTrends } from './trends';
|
|
15
|
+
import { getTweet, getTweets } from './tweets';
|
|
16
|
+
/**
|
|
17
|
+
* An interface to Twitter's undocumented API.
|
|
18
|
+
* Reusing Scraper objects is recommended to minimize the time spent authenticating unnecessarily.
|
|
19
|
+
*/
|
|
20
|
+
export class Scraper {
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new Scraper object. Scrapers maintain their own guest tokens for Twitter's internal API.
|
|
23
|
+
* Reusing Scraper objects is recommended to minimize the time spent authenticating unnecessarily.
|
|
24
|
+
*/
|
|
25
|
+
constructor() {
|
|
26
|
+
this.auth = new TwitterGuestAuth(bearerToken);
|
|
27
|
+
this.authTrends = new TwitterGuestAuth(bearerToken2);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fetches a Twitter profile.
|
|
31
|
+
* @param username The Twitter username of the profile to fetch, without an `@` at the beginning.
|
|
32
|
+
* @returns The requested profile.
|
|
33
|
+
*/
|
|
34
|
+
getProfile(username) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const res = yield getProfile(username, this.auth);
|
|
37
|
+
return this.handleResponse(res);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetches the user ID corresponding to the provided screen name.
|
|
42
|
+
* @param screenName The Twitter screen name of the profile to fetch.
|
|
43
|
+
* @returns The ID of the corresponding account.
|
|
44
|
+
*/
|
|
45
|
+
getUserIdByScreenName(screenName) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
const res = yield getUserIdByScreenName(screenName, this.auth);
|
|
48
|
+
return this.handleResponse(res);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Fetches tweets from Twitter.
|
|
53
|
+
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
54
|
+
* @param maxTweets The maximum number of tweets to return.
|
|
55
|
+
* @param includeReplies Whether or not replies should be included in the response.
|
|
56
|
+
* @param searchMode The category filter to apply to the search. Defaults to `Top`.
|
|
57
|
+
* @returns An async generator of tweets matching the provided filters.
|
|
58
|
+
*/
|
|
59
|
+
searchTweets(query, maxTweets, includeReplies, searchMode = SearchMode.Top) {
|
|
60
|
+
return searchTweets(query, maxTweets, includeReplies, searchMode, this.auth);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Fetches profiles from Twitter.
|
|
64
|
+
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
65
|
+
* @param maxProfiles The maximum number of profiles to return.
|
|
66
|
+
* @returns An async generator of tweets matching the provided filters.
|
|
67
|
+
*/
|
|
68
|
+
searchProfiles(query, maxProfiles) {
|
|
69
|
+
return searchProfiles(query, maxProfiles, this.auth);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Fetches tweets from Twitter.
|
|
73
|
+
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
74
|
+
* @param maxTweets The maximum number of tweets to return.
|
|
75
|
+
* @param includeReplies Whether or not replies should be included in the response.
|
|
76
|
+
* @param searchMode The category filter to apply to the search. Defaults to `Top`.
|
|
77
|
+
* @param cursor The search cursor, which can be passed into further requests for more results.
|
|
78
|
+
* @returns A page of results, containing a cursor that can be used in further requests.
|
|
79
|
+
*/
|
|
80
|
+
fetchSearchTweets(query, maxTweets, includeReplies, searchMode, cursor) {
|
|
81
|
+
return fetchSearchTweets(query, maxTweets, includeReplies, searchMode, this.auth, cursor);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Fetches profiles from Twitter.
|
|
85
|
+
* @param query The search query. Any Twitter-compatible query format can be used.
|
|
86
|
+
* @param maxProfiles The maximum number of profiles to return.
|
|
87
|
+
* @param cursor The search cursor, which can be passed into further requests for more results.
|
|
88
|
+
* @returns A page of results, containing a cursor that can be used in further requests.
|
|
89
|
+
*/
|
|
90
|
+
fetchSearchProfiles(query, maxProfiles, cursor) {
|
|
91
|
+
return fetchSearchProfiles(query, maxProfiles, this.auth, cursor);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Fetches the current trends from Twitter.
|
|
95
|
+
* @returns The current list of trends.
|
|
96
|
+
*/
|
|
97
|
+
getTrends() {
|
|
98
|
+
return getTrends(this.authTrends);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Fetches tweets from a Twitter user.
|
|
102
|
+
* @param user The user whose tweets should be returned.
|
|
103
|
+
* @param maxTweets The maximum number of tweets to return.
|
|
104
|
+
* @param includeReplies Whether or not to include tweet replies.
|
|
105
|
+
* @returns An async generator of tweets from the provided user.
|
|
106
|
+
*/
|
|
107
|
+
getTweets(user, maxTweets, includeReplies) {
|
|
108
|
+
return getTweets(user, maxTweets, includeReplies, this.auth);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Fetches a single tweet.
|
|
112
|
+
* @param id The ID of the tweet to fetch.
|
|
113
|
+
* @param includeReplies Whether or not to include tweet replies.
|
|
114
|
+
* @returns The request tweet, or `null` if it couldn't be fetched.
|
|
115
|
+
*/
|
|
116
|
+
getTweet(id, includeReplies) {
|
|
117
|
+
return getTweet(id, includeReplies, this.auth);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Returns if the scraper has a guest token. The token may not be valid.
|
|
121
|
+
* @returns `true` if the scraper has a guest token; otherwise `false`.
|
|
122
|
+
*/
|
|
123
|
+
hasGuestToken() {
|
|
124
|
+
return this.auth.hasToken() || this.authTrends.hasToken();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Sets the optional cookie to be used in requests.
|
|
128
|
+
* @param cookie The cookie to be used in requests.
|
|
129
|
+
* @returns This scraper instance.
|
|
130
|
+
*/
|
|
131
|
+
withCookie(cookie) {
|
|
132
|
+
this.auth.useCookie(cookie);
|
|
133
|
+
this.authTrends.useCookie(cookie);
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sets the optional CSRF token to be used in requests.
|
|
138
|
+
* @param token The CSRF token to be used in requests.
|
|
139
|
+
* @returns This scraper instance.
|
|
140
|
+
*/
|
|
141
|
+
withXCsrfToken(token) {
|
|
142
|
+
this.auth.useCsrfToken(token);
|
|
143
|
+
this.authTrends.useCsrfToken(token);
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
handleResponse(res) {
|
|
147
|
+
if (!res.success) {
|
|
148
|
+
throw res.err;
|
|
149
|
+
}
|
|
150
|
+
return res.value;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
153
|
//# sourceMappingURL=scraper.js.map
|
package/dist/search.js
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import { addApiParams, requestApi } from './api';
|
|
11
|
-
import { parseTweets, parseUsers, } from './timeline';
|
|
12
|
-
import { getTweetTimeline, getUserTimeline } from './timeline-async';
|
|
13
|
-
/**
|
|
14
|
-
* The categories that can be used in Twitter searches.
|
|
15
|
-
*/
|
|
16
|
-
export var SearchMode;
|
|
17
|
-
(function (SearchMode) {
|
|
18
|
-
SearchMode[SearchMode["Top"] = 0] = "Top";
|
|
19
|
-
SearchMode[SearchMode["Latest"] = 1] = "Latest";
|
|
20
|
-
SearchMode[SearchMode["Photos"] = 2] = "Photos";
|
|
21
|
-
SearchMode[SearchMode["Videos"] = 3] = "Videos";
|
|
22
|
-
SearchMode[SearchMode["Users"] = 4] = "Users";
|
|
23
|
-
})(SearchMode || (SearchMode = {}));
|
|
24
|
-
export function searchTweets(query, maxTweets, includeReplies, searchMode, auth) {
|
|
25
|
-
return getTweetTimeline(query, maxTweets, (q, mt, c) => {
|
|
26
|
-
return fetchSearchTweets(q, mt, includeReplies, searchMode, auth, c);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export function searchProfiles(query, maxProfiles, auth) {
|
|
30
|
-
return getUserTimeline(query, maxProfiles, (q, mt, c) => {
|
|
31
|
-
return fetchSearchProfiles(q, mt, auth, c);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
export function fetchSearchTweets(query, maxTweets, includeReplies, searchMode, auth, cursor) {
|
|
35
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
const timeline = yield getSearchTimeline(query, maxTweets, includeReplies, searchMode, auth, cursor);
|
|
37
|
-
return parseTweets(timeline);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
export function fetchSearchProfiles(query, maxProfiles, auth, cursor) {
|
|
41
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
const timeline = yield getSearchTimeline(query, maxProfiles, false, SearchMode.Users, auth, cursor);
|
|
43
|
-
return parseUsers(timeline);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
function getSearchTimeline(query, maxItems, includeReplies, searchMode, auth, cursor) {
|
|
47
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
if (maxItems > 50) {
|
|
49
|
-
maxItems = 50;
|
|
50
|
-
}
|
|
51
|
-
const params = new URLSearchParams();
|
|
52
|
-
addApiParams(params, includeReplies);
|
|
53
|
-
params.set('q', query);
|
|
54
|
-
params.set('count', `${maxItems}`);
|
|
55
|
-
params.set('query_source', 'typed_query');
|
|
56
|
-
params.set('pc', '1');
|
|
57
|
-
params.set('spelling_corrections', '1');
|
|
58
|
-
if (cursor != null && cursor != '') {
|
|
59
|
-
params.set('cursor', cursor);
|
|
60
|
-
}
|
|
61
|
-
switch (searchMode) {
|
|
62
|
-
case SearchMode.Latest:
|
|
63
|
-
params.set('tweet_search_mode', 'live');
|
|
64
|
-
break;
|
|
65
|
-
case SearchMode.Photos:
|
|
66
|
-
params.set('result_filter', 'image');
|
|
67
|
-
break;
|
|
68
|
-
case SearchMode.Videos:
|
|
69
|
-
params.set('result_filter', 'video');
|
|
70
|
-
break;
|
|
71
|
-
case SearchMode.Users:
|
|
72
|
-
params.set('result_filter', 'user');
|
|
73
|
-
break;
|
|
74
|
-
default:
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
const res = yield requestApi(`https://twitter.com/i/api/2/search/adaptive.json?${params.toString()}`, auth);
|
|
78
|
-
if (!res.success) {
|
|
79
|
-
throw res.err;
|
|
80
|
-
}
|
|
81
|
-
return res.value;
|
|
82
|
-
});
|
|
83
|
-
}
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { addApiParams, requestApi } from './api';
|
|
11
|
+
import { parseTweets, parseUsers, } from './timeline';
|
|
12
|
+
import { getTweetTimeline, getUserTimeline } from './timeline-async';
|
|
13
|
+
/**
|
|
14
|
+
* The categories that can be used in Twitter searches.
|
|
15
|
+
*/
|
|
16
|
+
export var SearchMode;
|
|
17
|
+
(function (SearchMode) {
|
|
18
|
+
SearchMode[SearchMode["Top"] = 0] = "Top";
|
|
19
|
+
SearchMode[SearchMode["Latest"] = 1] = "Latest";
|
|
20
|
+
SearchMode[SearchMode["Photos"] = 2] = "Photos";
|
|
21
|
+
SearchMode[SearchMode["Videos"] = 3] = "Videos";
|
|
22
|
+
SearchMode[SearchMode["Users"] = 4] = "Users";
|
|
23
|
+
})(SearchMode || (SearchMode = {}));
|
|
24
|
+
export function searchTweets(query, maxTweets, includeReplies, searchMode, auth) {
|
|
25
|
+
return getTweetTimeline(query, maxTweets, (q, mt, c) => {
|
|
26
|
+
return fetchSearchTweets(q, mt, includeReplies, searchMode, auth, c);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function searchProfiles(query, maxProfiles, auth) {
|
|
30
|
+
return getUserTimeline(query, maxProfiles, (q, mt, c) => {
|
|
31
|
+
return fetchSearchProfiles(q, mt, auth, c);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function fetchSearchTweets(query, maxTweets, includeReplies, searchMode, auth, cursor) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const timeline = yield getSearchTimeline(query, maxTweets, includeReplies, searchMode, auth, cursor);
|
|
37
|
+
return parseTweets(timeline);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function fetchSearchProfiles(query, maxProfiles, auth, cursor) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const timeline = yield getSearchTimeline(query, maxProfiles, false, SearchMode.Users, auth, cursor);
|
|
43
|
+
return parseUsers(timeline);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function getSearchTimeline(query, maxItems, includeReplies, searchMode, auth, cursor) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
if (maxItems > 50) {
|
|
49
|
+
maxItems = 50;
|
|
50
|
+
}
|
|
51
|
+
const params = new URLSearchParams();
|
|
52
|
+
addApiParams(params, includeReplies);
|
|
53
|
+
params.set('q', query);
|
|
54
|
+
params.set('count', `${maxItems}`);
|
|
55
|
+
params.set('query_source', 'typed_query');
|
|
56
|
+
params.set('pc', '1');
|
|
57
|
+
params.set('spelling_corrections', '1');
|
|
58
|
+
if (cursor != null && cursor != '') {
|
|
59
|
+
params.set('cursor', cursor);
|
|
60
|
+
}
|
|
61
|
+
switch (searchMode) {
|
|
62
|
+
case SearchMode.Latest:
|
|
63
|
+
params.set('tweet_search_mode', 'live');
|
|
64
|
+
break;
|
|
65
|
+
case SearchMode.Photos:
|
|
66
|
+
params.set('result_filter', 'image');
|
|
67
|
+
break;
|
|
68
|
+
case SearchMode.Videos:
|
|
69
|
+
params.set('result_filter', 'video');
|
|
70
|
+
break;
|
|
71
|
+
case SearchMode.Users:
|
|
72
|
+
params.set('result_filter', 'user');
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
const res = yield requestApi(`https://twitter.com/i/api/2/search/adaptive.json?${params.toString()}`, auth);
|
|
78
|
+
if (!res.success) {
|
|
79
|
+
throw res.err;
|
|
80
|
+
}
|
|
81
|
+
return res.value;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
84
|
//# sourceMappingURL=search.js.map
|
package/dist/timeline-async.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
2
|
-
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
3
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
5
|
-
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
6
|
-
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
7
|
-
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
8
|
-
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
9
|
-
function fulfill(value) { resume("next", value); }
|
|
10
|
-
function reject(value) { resume("throw", value); }
|
|
11
|
-
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
12
|
-
};
|
|
13
|
-
export function getUserTimeline(query, maxProfiles, fetchFunc) {
|
|
14
|
-
return __asyncGenerator(this, arguments, function* getUserTimeline_1() {
|
|
15
|
-
let nProfiles = 0;
|
|
16
|
-
let cursor = undefined;
|
|
17
|
-
while (nProfiles < maxProfiles) {
|
|
18
|
-
const batch = yield __await(fetchFunc(query, maxProfiles, cursor));
|
|
19
|
-
const { profiles, next } = batch;
|
|
20
|
-
if (profiles.length === 0) {
|
|
21
|
-
break;
|
|
22
|
-
}
|
|
23
|
-
for (const profile of profiles) {
|
|
24
|
-
if (nProfiles < maxProfiles) {
|
|
25
|
-
cursor = next;
|
|
26
|
-
yield yield __await(profile);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
nProfiles++;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
export function getTweetTimeline(query, maxTweets, fetchFunc) {
|
|
37
|
-
return __asyncGenerator(this, arguments, function* getTweetTimeline_1() {
|
|
38
|
-
let nTweets = 0;
|
|
39
|
-
let cursor = undefined;
|
|
40
|
-
while (nTweets < maxTweets) {
|
|
41
|
-
const batch = yield __await(fetchFunc(query, maxTweets, cursor));
|
|
42
|
-
const { tweets, next } = batch;
|
|
43
|
-
if (tweets.length === 0) {
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
for (const tweet of tweets) {
|
|
47
|
-
if (nTweets < maxTweets) {
|
|
48
|
-
cursor = next;
|
|
49
|
-
yield yield __await(tweet);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
nTweets++;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
1
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
2
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
3
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
5
|
+
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
6
|
+
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
7
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
8
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
9
|
+
function fulfill(value) { resume("next", value); }
|
|
10
|
+
function reject(value) { resume("throw", value); }
|
|
11
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
12
|
+
};
|
|
13
|
+
export function getUserTimeline(query, maxProfiles, fetchFunc) {
|
|
14
|
+
return __asyncGenerator(this, arguments, function* getUserTimeline_1() {
|
|
15
|
+
let nProfiles = 0;
|
|
16
|
+
let cursor = undefined;
|
|
17
|
+
while (nProfiles < maxProfiles) {
|
|
18
|
+
const batch = yield __await(fetchFunc(query, maxProfiles, cursor));
|
|
19
|
+
const { profiles, next } = batch;
|
|
20
|
+
if (profiles.length === 0) {
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
for (const profile of profiles) {
|
|
24
|
+
if (nProfiles < maxProfiles) {
|
|
25
|
+
cursor = next;
|
|
26
|
+
yield yield __await(profile);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
nProfiles++;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function getTweetTimeline(query, maxTweets, fetchFunc) {
|
|
37
|
+
return __asyncGenerator(this, arguments, function* getTweetTimeline_1() {
|
|
38
|
+
let nTweets = 0;
|
|
39
|
+
let cursor = undefined;
|
|
40
|
+
while (nTweets < maxTweets) {
|
|
41
|
+
const batch = yield __await(fetchFunc(query, maxTweets, cursor));
|
|
42
|
+
const { tweets, next } = batch;
|
|
43
|
+
if (tweets.length === 0) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
for (const tweet of tweets) {
|
|
47
|
+
if (nTweets < maxTweets) {
|
|
48
|
+
cursor = next;
|
|
49
|
+
yield yield __await(tweet);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
nTweets++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
59
|
//# sourceMappingURL=timeline-async.js.map
|