@pipedream/twitter 0.3.10 → 1.0.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/README.md +20 -71
- package/dist/actions/add-user-to-list/add-user-to-list.d.ts +380 -0
- package/dist/actions/add-user-to-list/add-user-to-list.mjs +42 -0
- package/dist/actions/create-tweet/create-tweet.d.ts +163 -0
- package/dist/actions/create-tweet/create-tweet.mjs +78 -0
- package/dist/actions/delete-tweet/delete-tweet.d.ts +252 -0
- package/dist/actions/delete-tweet/delete-tweet.mjs +28 -0
- package/dist/actions/follow-user/follow-user.d.ts +255 -0
- package/dist/actions/follow-user/follow-user.mjs +37 -0
- package/dist/actions/get-tweet/get-tweet.d.ts +1006 -0
- package/dist/actions/get-tweet/get-tweet.mjs +35 -0
- package/dist/actions/get-user/get-user.d.ts +634 -0
- package/dist/actions/get-user/get-user.mjs +37 -0
- package/dist/actions/like-tweet/like-tweet.d.ts +252 -0
- package/dist/actions/like-tweet/like-tweet.mjs +30 -0
- package/dist/actions/list-favorites/list-favorites.d.ts +1138 -0
- package/dist/actions/list-favorites/list-favorites.mjs +52 -0
- package/dist/actions/list-followers/list-followers.d.ts +765 -0
- package/dist/actions/list-followers/list-followers.mjs +52 -0
- package/dist/actions/list-lists/list-lists.d.ts +762 -0
- package/dist/actions/list-lists/list-lists.mjs +52 -0
- package/dist/actions/list-mentions/list-mentions.d.ts +1136 -0
- package/dist/actions/list-mentions/list-mentions.mjs +52 -0
- package/dist/actions/list-user-tweets/list-user-tweets.d.ts +1138 -0
- package/dist/actions/list-user-tweets/list-user-tweets.mjs +52 -0
- package/dist/actions/retweet/retweet.d.ts +252 -0
- package/dist/actions/retweet/retweet.mjs +31 -0
- package/dist/actions/simple-search/simple-search.d.ts +1137 -0
- package/dist/actions/simple-search/simple-search.mjs +51 -0
- package/dist/actions/simple-search-in-list/simple-search-in-list.d.ts +1142 -0
- package/dist/actions/simple-search-in-list/simple-search-in-list.mjs +60 -0
- package/dist/actions/unfollow-user/unfollow-user.d.ts +255 -0
- package/dist/actions/unfollow-user/unfollow-user.mjs +33 -0
- package/dist/actions/unlike-tweet/unlike-tweet.d.ts +252 -0
- package/dist/actions/unlike-tweet/unlike-tweet.mjs +28 -0
- package/dist/app/twitter.app.d.ts +127 -0
- package/dist/app/twitter.app.mjs +341 -0
- package/dist/common/dataFields.d.ts +6 -0
- package/dist/common/dataFields.mjs +80 -0
- package/dist/common/expansions.d.ts +3 -0
- package/dist/common/expansions.mjs +17 -0
- package/dist/common/methods.d.ts +20 -0
- package/dist/common/methods.mjs +48 -0
- package/dist/common/propGroups.d.ts +1509 -0
- package/dist/common/propGroups.mjs +82 -0
- package/dist/common/types/fields.d.ts +18 -0
- package/dist/common/types/fields.mjs +1 -0
- package/dist/common/types/requestParams.d.ts +103 -0
- package/dist/common/types/requestParams.mjs +1 -0
- package/dist/common/types/responseSchemas.d.ts +42 -0
- package/dist/common/types/responseSchemas.mjs +1 -0
- package/dist/sources/common/base.d.ts +149 -0
- package/dist/sources/common/base.mjs +62 -0
- package/dist/sources/common/cacheUserId.d.ts +7 -0
- package/dist/sources/common/cacheUserId.mjs +18 -0
- package/dist/sources/common/getItemSummary.d.ts +4 -0
- package/dist/sources/common/getItemSummary.mjs +12 -0
- package/dist/sources/new-follower-of-user/new-follower-of-user.d.ts +650 -0
- package/dist/sources/new-follower-of-user/new-follower-of-user.mjs +49 -0
- package/dist/sources/new-list-followed/new-list-followed.d.ts +649 -0
- package/dist/sources/new-list-followed/new-list-followed.mjs +50 -0
- package/dist/sources/new-tweet-in-list/new-tweet-in-list.d.ts +1021 -0
- package/dist/sources/new-tweet-in-list/new-tweet-in-list.mjs +46 -0
- package/dist/sources/new-tweet-liked-by-user/new-tweet-liked-by-user.d.ts +1023 -0
- package/dist/sources/new-tweet-liked-by-user/new-tweet-liked-by-user.mjs +49 -0
- package/dist/sources/new-tweet-posted-by-user/new-tweet-posted-by-user.d.ts +1023 -0
- package/dist/sources/new-tweet-posted-by-user/new-tweet-posted-by-user.mjs +49 -0
- package/dist/sources/new-tweet-posted-matching-query/new-tweet-posted-matching-query.d.ts +1021 -0
- package/dist/sources/new-tweet-posted-matching-query/new-tweet-posted-matching-query.mjs +51 -0
- package/dist/sources/new-unfollower-of-user/new-unfollower-of-user.d.ts +273 -0
- package/dist/sources/new-unfollower-of-user/new-unfollower-of-user.mjs +75 -0
- package/dist/sources/new-user-followed/new-user-followed.d.ts +649 -0
- package/dist/sources/new-user-followed/new-user-followed.mjs +50 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +10 -13
- package/actions/add-user-to-list/add-user-to-list.mjs +0 -62
- package/actions/advanced-search/advanced-search.mjs +0 -113
- package/actions/common.mjs +0 -29
- package/actions/create-tweet/create-tweet.mjs +0 -146
- package/actions/delete-tweet/delete-tweet.mjs +0 -42
- package/actions/follow-user/follow-user.mjs +0 -48
- package/actions/get-tweet/get-tweet.mjs +0 -42
- package/actions/get-user/get-user.mjs +0 -50
- package/actions/like-tweet/like-tweet.mjs +0 -42
- package/actions/list-favorites/list-favorites.mjs +0 -63
- package/actions/list-followers/list-followers.mjs +0 -67
- package/actions/list-lists/list-lists.mjs +0 -69
- package/actions/list-mentions/list-mentions.mjs +0 -55
- package/actions/list-pending-followers/list-pending-followers.mjs +0 -32
- package/actions/list-retweets/list-retweets.mjs +0 -54
- package/actions/list-user-tweets/list-user-tweets.mjs +0 -80
- package/actions/retweet/retweet.mjs +0 -27
- package/actions/simple-search/simple-search.mjs +0 -62
- package/actions/simple-search-in-list/simple-search-in-list.mjs +0 -48
- package/actions/unfollow-user/unfollow-user.mjs +0 -48
- package/actions/unlike-tweet/unlike-tweet.mjs +0 -40
- package/actions/upload-media/upload-media.mjs +0 -114
- package/old.md +0 -169
- package/sources/common/followed.mjs +0 -38
- package/sources/common/followers.mjs +0 -159
- package/sources/common/tweets.mjs +0 -155
- package/sources/language-codes.mjs +0 -742
- package/sources/my-liked-tweets/my-liked-tweets.mjs +0 -30
- package/sources/my-tweets/my-tweets.mjs +0 -48
- package/sources/new-follower-of-me/new-follower-of-me.mjs +0 -69
- package/sources/new-follower-of-user/new-follower-of-user.mjs +0 -25
- package/sources/new-list-followed/new-list-followed.mjs +0 -24
- package/sources/new-trends-by-geo/new-trends-by-geo.mjs +0 -40
- package/sources/new-tweet-in-list/new-tweet-in-list.mjs +0 -49
- package/sources/new-unfollower-of-me/new-unfollower-of-me.mjs +0 -16
- package/sources/new-unfollower-of-user/new-unfollower-of-user.mjs +0 -25
- package/sources/new-user-followed/new-user-followed.mjs +0 -25
- package/sources/search-mentions/search-mentions.mjs +0 -144
- package/sources/tweets-liked-by-user/tweets-liked-by-user.mjs +0 -38
- package/sources/user-tweets/user-tweets.mjs +0 -49
- package/sources/watch-retweets-of-me/watch-retweets-of-me.mjs +0 -36
- package/sources/watch-retweets-of-my-tweet/watch-retweets-of-my-tweet.mjs +0 -44
- package/sources/watch-retweets-of-user-tweet/watch-retweets-of-user-tweet.mjs +0 -34
- package/twitter.app.mjs +0 -1161
package/twitter.app.mjs
DELETED
|
@@ -1,1161 +0,0 @@
|
|
|
1
|
-
import { axios } from "@pipedream/platform";
|
|
2
|
-
import get from "lodash/get.js";
|
|
3
|
-
import { DateTime } from "luxon";
|
|
4
|
-
import retry from "async-retry";
|
|
5
|
-
import isoLanguages from "./sources/language-codes.mjs";
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
type: "app",
|
|
9
|
-
app: "twitter",
|
|
10
|
-
propDefinitions: {
|
|
11
|
-
q: {
|
|
12
|
-
type: "string",
|
|
13
|
-
label: "Search Term",
|
|
14
|
-
description: "Search for keywords `star wars`, screen names `@starwars`, or hashtags `#starwars`. You can also use Twitter's [standard search operators](https://developer.twitter.com/en/docs/tweets/rules-and-filtering/overview/standard-operators).",
|
|
15
|
-
},
|
|
16
|
-
keywordFilter: {
|
|
17
|
-
type: "string",
|
|
18
|
-
label: "Keywords",
|
|
19
|
-
description: "Filter tweets based on keywords `star wars`, user mentions `@starwars`, or hashtags `#starwars`. You can also use Twitter's [standard search operators](https://developer.twitter.com/en/docs/tweets/rules-and-filtering/overview/standard-operators).",
|
|
20
|
-
optional: true,
|
|
21
|
-
},
|
|
22
|
-
resultType: {
|
|
23
|
-
type: "string",
|
|
24
|
-
label: "Result Type",
|
|
25
|
-
description: "Specifies the type of results you want to retrieve.",
|
|
26
|
-
optional: true,
|
|
27
|
-
options: [
|
|
28
|
-
{
|
|
29
|
-
label: "Recent",
|
|
30
|
-
value: "recent",
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
label: "Popular",
|
|
34
|
-
value: "popular",
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
label: "Mixed",
|
|
38
|
-
value: "mixed",
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
default: "recent",
|
|
42
|
-
},
|
|
43
|
-
count: {
|
|
44
|
-
type: "integer",
|
|
45
|
-
min: 1,
|
|
46
|
-
max: 100,
|
|
47
|
-
label: "Count (advanced)",
|
|
48
|
-
description: "The maximum number of tweets to return per API request (up to `100`)",
|
|
49
|
-
optional: true,
|
|
50
|
-
default: 100,
|
|
51
|
-
},
|
|
52
|
-
maxRequests: {
|
|
53
|
-
type: "integer",
|
|
54
|
-
min: 1,
|
|
55
|
-
max: 180,
|
|
56
|
-
label: "Max API Requests per Execution (advanced)",
|
|
57
|
-
description: "The maximum number of API requests to make per execution (e.g., multiple requests are required to retrieve paginated results). **Note:** Twitter [rate limits API requests](https://developer.twitter.com/en/docs/basics/rate-limiting) per 15 minute interval.",
|
|
58
|
-
optional: true,
|
|
59
|
-
default: 1,
|
|
60
|
-
},
|
|
61
|
-
from: {
|
|
62
|
-
type: "string",
|
|
63
|
-
label: "From",
|
|
64
|
-
description: "The screen name of the user (e.g., `pipedream`)",
|
|
65
|
-
},
|
|
66
|
-
geocode: {
|
|
67
|
-
type: "string",
|
|
68
|
-
label: "Geocode",
|
|
69
|
-
description: "Returns tweets by users located within a given radius of the given latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall back to their Twitter profile. The parameter value is specified by `latitude,longitude,radius`, where radius units must be specified as either `mi` (miles) or `km` (kilometers). Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this geocode parameter to search near geocodes directly.",
|
|
70
|
-
optional: true,
|
|
71
|
-
},
|
|
72
|
-
includeRetweets: {
|
|
73
|
-
type: "string",
|
|
74
|
-
label: "Retweets",
|
|
75
|
-
description: "Select whether to **include**, **exclude** or **only include** retweets in emitted events.",
|
|
76
|
-
optional: true,
|
|
77
|
-
options: [
|
|
78
|
-
{
|
|
79
|
-
label: "Include",
|
|
80
|
-
value: "include",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
label: "Exclude",
|
|
84
|
-
value: "exclude",
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
label: "Only include retweets",
|
|
88
|
-
value: "filter",
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
default: "include",
|
|
92
|
-
},
|
|
93
|
-
includeReplies: {
|
|
94
|
-
type: "string",
|
|
95
|
-
label: "Replies",
|
|
96
|
-
description: "Select whether to **include**, **exclude** or **only include** replies in emitted events.",
|
|
97
|
-
optional: true,
|
|
98
|
-
options: [
|
|
99
|
-
{
|
|
100
|
-
label: "Include",
|
|
101
|
-
value: "include",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
label: "Exclude",
|
|
105
|
-
value: "exclude",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
label: "Only include replies",
|
|
109
|
-
value: "filter",
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
default: "include",
|
|
113
|
-
},
|
|
114
|
-
enrichTweets: {
|
|
115
|
-
type: "boolean",
|
|
116
|
-
label: "Enrich Tweets",
|
|
117
|
-
description: "Enrich each Tweet with epoch (milliseconds) and ISO 8601 representations of Twitter's `created_at` timestamp, the Tweet URL, and the profile URL for the author.",
|
|
118
|
-
optional: true,
|
|
119
|
-
default: true,
|
|
120
|
-
},
|
|
121
|
-
locale: {
|
|
122
|
-
type: "string",
|
|
123
|
-
label: "Locale",
|
|
124
|
-
description: "Specify the language of the query you are sending (only `ja` is currently effective). This is intended for language-specific consumers and the default should work in the majority of cases.",
|
|
125
|
-
optional: true,
|
|
126
|
-
},
|
|
127
|
-
lang: {
|
|
128
|
-
type: "string[]",
|
|
129
|
-
label: "Languages",
|
|
130
|
-
description: "Restricts tweets to the given languages. Language detection is best-effort. When unsure, leave blank.",
|
|
131
|
-
default: [],
|
|
132
|
-
optional: true,
|
|
133
|
-
async options(context) {
|
|
134
|
-
const { page } = context;
|
|
135
|
-
if (page !== 0) {
|
|
136
|
-
return {
|
|
137
|
-
options: [],
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return isoLanguages.map((isoLanguage) => {
|
|
142
|
-
const {
|
|
143
|
-
English: language,
|
|
144
|
-
alpha2: code,
|
|
145
|
-
} = isoLanguage;
|
|
146
|
-
return {
|
|
147
|
-
label: `${language} (${code})`,
|
|
148
|
-
value: code,
|
|
149
|
-
};
|
|
150
|
-
});
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
sinceId: {
|
|
154
|
-
type: "string",
|
|
155
|
-
label: "Since ID",
|
|
156
|
-
description: "Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets that can be accessed through the API. If the limit of Tweets has occurred since the `since_id`, the 'since_id` will be forced to the oldest ID available.",
|
|
157
|
-
optional: true,
|
|
158
|
-
},
|
|
159
|
-
screenName: {
|
|
160
|
-
type: "string",
|
|
161
|
-
label: "Screen Name",
|
|
162
|
-
description: "The screen name of the user (e.g., `pipedream`)",
|
|
163
|
-
},
|
|
164
|
-
trendLocation: {
|
|
165
|
-
type: "string",
|
|
166
|
-
label: "Location",
|
|
167
|
-
description: "Location of trending topics",
|
|
168
|
-
async options() {
|
|
169
|
-
const trendLocations = await this.getTrendLocations();
|
|
170
|
-
return trendLocations.map((location) => {
|
|
171
|
-
return {
|
|
172
|
-
label: `${location.name}, ${location.countryCode} (${location.placeType.name})`,
|
|
173
|
-
value: location.woeid,
|
|
174
|
-
};
|
|
175
|
-
});
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
includeEntities: {
|
|
179
|
-
type: "boolean",
|
|
180
|
-
label: "Entities",
|
|
181
|
-
description: "The tweet 'entities' node will not be included when set to false",
|
|
182
|
-
default: false,
|
|
183
|
-
},
|
|
184
|
-
includeUserEntities: {
|
|
185
|
-
type: "boolean",
|
|
186
|
-
label: "User Entities",
|
|
187
|
-
description: "The user 'entities' node will not be included when set to false",
|
|
188
|
-
default: false,
|
|
189
|
-
},
|
|
190
|
-
tweetID: {
|
|
191
|
-
type: "string",
|
|
192
|
-
label: "Tweet ID",
|
|
193
|
-
description: "The numerical ID of the tweet ID (also known as \"status\")",
|
|
194
|
-
},
|
|
195
|
-
userId: {
|
|
196
|
-
type: "string",
|
|
197
|
-
label: "User ID",
|
|
198
|
-
description: "The numerical ID of the user to lookup",
|
|
199
|
-
},
|
|
200
|
-
list: {
|
|
201
|
-
type: "string",
|
|
202
|
-
label: "List",
|
|
203
|
-
description: "List to select",
|
|
204
|
-
async options({ prevContext }) {
|
|
205
|
-
const { cursor } = prevContext;
|
|
206
|
-
const params = cursor
|
|
207
|
-
? {
|
|
208
|
-
cursor,
|
|
209
|
-
}
|
|
210
|
-
: null;
|
|
211
|
-
const lists = await this.getLists({
|
|
212
|
-
params,
|
|
213
|
-
});
|
|
214
|
-
const { next_cursor: nextCursor } = lists;
|
|
215
|
-
return {
|
|
216
|
-
options: lists.map((list) => {
|
|
217
|
-
return {
|
|
218
|
-
label: list.name,
|
|
219
|
-
value: list.id_str,
|
|
220
|
-
};
|
|
221
|
-
}),
|
|
222
|
-
context: {
|
|
223
|
-
cursor: nextCursor,
|
|
224
|
-
},
|
|
225
|
-
};
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
listSlug: {
|
|
229
|
-
type: "string",
|
|
230
|
-
label: "List",
|
|
231
|
-
description: "List to select",
|
|
232
|
-
async options({ prevContext }) {
|
|
233
|
-
const { cursor } = prevContext;
|
|
234
|
-
const params = cursor
|
|
235
|
-
? {
|
|
236
|
-
cursor,
|
|
237
|
-
}
|
|
238
|
-
: null;
|
|
239
|
-
const lists = await this.getLists({
|
|
240
|
-
params,
|
|
241
|
-
});
|
|
242
|
-
const { next_cursor: nextCursor } = lists;
|
|
243
|
-
return {
|
|
244
|
-
options: lists.map((list) => {
|
|
245
|
-
return {
|
|
246
|
-
label: list.name,
|
|
247
|
-
value: list.slug,
|
|
248
|
-
};
|
|
249
|
-
}),
|
|
250
|
-
context: {
|
|
251
|
-
cursor: nextCursor,
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
status: {
|
|
257
|
-
type: "string",
|
|
258
|
-
label: "Status",
|
|
259
|
-
description: `The text of the status update. Note: In order to comply with Twitter’s
|
|
260
|
-
terms of service, this text will have all @mentions removed.
|
|
261
|
-
Please refer to [our docs for more details](https://pipedream.com/docs/apps/twitter/#limitations-on-mentions).`,
|
|
262
|
-
},
|
|
263
|
-
inReplyToStatusId: {
|
|
264
|
-
type: "string",
|
|
265
|
-
label: "In Reply To Status ID",
|
|
266
|
-
description: `The ID of an existing status that the update is in reply to. Note: This
|
|
267
|
-
parameter will be ignored unless the author of the Tweet this parameter
|
|
268
|
-
references is mentioned within the status text. Therefore, you must
|
|
269
|
-
include \`@username\` , where \`username\` is the author of the referenced
|
|
270
|
-
Tweet, within the update.`,
|
|
271
|
-
optional: true,
|
|
272
|
-
},
|
|
273
|
-
autoPopulateReplyMetadata: {
|
|
274
|
-
type: "boolean",
|
|
275
|
-
label: "Auto Populate Reply Metadata",
|
|
276
|
-
description: `If set to true and used with \`in_reply_to_status_id\`, leading
|
|
277
|
-
\`@mentions\` will be looked up from the original Tweet, and added to the
|
|
278
|
-
new Tweet from there. This will append \`@mentions\` into the metadata
|
|
279
|
-
of an extended Tweet as a reply chain grows, until the limit on
|
|
280
|
-
\`@mentions\` is reached. In cases where the original Tweet has been
|
|
281
|
-
deleted, the reply will fail.`,
|
|
282
|
-
optional: true,
|
|
283
|
-
default: false,
|
|
284
|
-
},
|
|
285
|
-
excludeReplyUserIds: {
|
|
286
|
-
type: "string",
|
|
287
|
-
label: "Exclude Reply User Ids",
|
|
288
|
-
description: `When used with \`auto_populate_reply_metadata\`, a
|
|
289
|
-
comma-separated list of user ids which will be removed from the
|
|
290
|
-
server-generated \`@mentions\` prefix on an extended Tweet. Note that
|
|
291
|
-
the leading \`@mention\` cannot be removed as it would break the
|
|
292
|
-
\`in-reply-to-status-id\` semantics. Attempting to remove it will be
|
|
293
|
-
silently ignored.`,
|
|
294
|
-
optional: true,
|
|
295
|
-
},
|
|
296
|
-
attachmentUrl: {
|
|
297
|
-
type: "string",
|
|
298
|
-
label: "Attachment URL",
|
|
299
|
-
description: `In order for a URL to not be counted in the status body of an extended
|
|
300
|
-
Tweet, provide a URL as a Tweet attachment. This URL must be a
|
|
301
|
-
Tweet permalink or Direct Message deep link. Arbitrary, non-Twitter
|
|
302
|
-
URLs must remain in the status text. URLs passed to the
|
|
303
|
-
\`attachment_url\` parameter not matching either a Tweet permalink or
|
|
304
|
-
Direct Message deep link will fail at Tweet creation and cause an
|
|
305
|
-
exception.`,
|
|
306
|
-
optional: true,
|
|
307
|
-
},
|
|
308
|
-
mediaIds: {
|
|
309
|
-
type: "string",
|
|
310
|
-
label: "Media IDs",
|
|
311
|
-
description: `A comma-delimited list of \`media_ids\` to associate with the Tweet. You
|
|
312
|
-
may include up to 4 photos or 1 animated GIF or 1 video in a Tweet.`,
|
|
313
|
-
optional: true,
|
|
314
|
-
},
|
|
315
|
-
possiblySensitive: {
|
|
316
|
-
type: "boolean",
|
|
317
|
-
label: "Possibly Sensitive",
|
|
318
|
-
description: `If you upload Tweet media that might be considered sensitive content
|
|
319
|
-
such as nudity or medical procedures, you must set this value to true.
|
|
320
|
-
If this parameter is included in your request, it will override the user’s
|
|
321
|
-
preferences.`,
|
|
322
|
-
optional: true,
|
|
323
|
-
},
|
|
324
|
-
lat: {
|
|
325
|
-
type: "string",
|
|
326
|
-
label: "Latitude",
|
|
327
|
-
description: "The latitude of the location this Tweet refers to.",
|
|
328
|
-
optional: true,
|
|
329
|
-
},
|
|
330
|
-
long: {
|
|
331
|
-
type: "string",
|
|
332
|
-
label: "Longitude",
|
|
333
|
-
description: "The longitude of the location this Tweet refers to.",
|
|
334
|
-
optional: true,
|
|
335
|
-
},
|
|
336
|
-
placeId: {
|
|
337
|
-
type: "string",
|
|
338
|
-
label: "Place ID",
|
|
339
|
-
description: "A place in the world. These IDs can be retrieved from [geo/reverse_geocode](https://developer.twitter.com/en/docs/twitter-api/v1/geo/place-information/api-reference/get-geo-id-place_id)",
|
|
340
|
-
optional: true,
|
|
341
|
-
},
|
|
342
|
-
displayCoordinates: {
|
|
343
|
-
type: "boolean",
|
|
344
|
-
label: "Display Coordinates",
|
|
345
|
-
description: `Whether or not to put a pin on the exact coordinates a Tweet has been
|
|
346
|
-
sent from.`,
|
|
347
|
-
optional: true,
|
|
348
|
-
},
|
|
349
|
-
trimUser: {
|
|
350
|
-
type: "boolean",
|
|
351
|
-
label: "Trim User",
|
|
352
|
-
description: `When set to true, the response will include a user object including
|
|
353
|
-
only the author's ID.`,
|
|
354
|
-
optional: true,
|
|
355
|
-
default: false,
|
|
356
|
-
},
|
|
357
|
-
enableDmcommands: {
|
|
358
|
-
type: "boolean",
|
|
359
|
-
label: "Enable DM Commands",
|
|
360
|
-
description: `When set to true, enables shortcode commands for sending Direct
|
|
361
|
-
Messages as part of the status text to send a Direct Message to a user.
|
|
362
|
-
When set to false, it turns off this behavior and includes any leading
|
|
363
|
-
characters in the status text that is posted.`,
|
|
364
|
-
optional: true,
|
|
365
|
-
default: false,
|
|
366
|
-
},
|
|
367
|
-
failDmcommands: {
|
|
368
|
-
type: "boolean",
|
|
369
|
-
label: "Fail DM Commands",
|
|
370
|
-
description: `When set to true, causes any status text that starts with shortcode
|
|
371
|
-
commands to return an API error. When set to false, allows shortcode
|
|
372
|
-
commands to be sent in the status text and acted on by the API.`,
|
|
373
|
-
optional: true,
|
|
374
|
-
default: true,
|
|
375
|
-
},
|
|
376
|
-
cardUri: {
|
|
377
|
-
type: "string",
|
|
378
|
-
label: "Card URI",
|
|
379
|
-
description: `Associate an ads card with the Tweet using the card_uri value from any
|
|
380
|
-
ads card response.`,
|
|
381
|
-
optional: true,
|
|
382
|
-
},
|
|
383
|
-
imageUrl: {
|
|
384
|
-
type: "string",
|
|
385
|
-
label: "Profile Image URL",
|
|
386
|
-
description: "The avatar image for the profile",
|
|
387
|
-
},
|
|
388
|
-
skipStatus: {
|
|
389
|
-
type: "boolean",
|
|
390
|
-
label: "Skip Status",
|
|
391
|
-
description: "When set to `true`, statuses will not be included in the returned user objects",
|
|
392
|
-
optional: true,
|
|
393
|
-
default: false,
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
methods: {
|
|
397
|
-
_isRetriableStatusCode(statusCode) {
|
|
398
|
-
// Taken from the Twitter API docs:
|
|
399
|
-
// https://developer.twitter.com/en/docs/twitter-ads-api/response-codes
|
|
400
|
-
return [
|
|
401
|
-
423, // LOCK_ACQUISITION_TIMEOUT
|
|
402
|
-
429, // TOO_MANY_REQUESTS | TWEET_RATE_LIMIT_EXCEEDED
|
|
403
|
-
500, // INTERNAL_ERROR
|
|
404
|
-
503, // SERVICE_UNAVAILABLE | OVER_CAPACITY
|
|
405
|
-
].includes(statusCode);
|
|
406
|
-
},
|
|
407
|
-
async _withRetries(apiCall) {
|
|
408
|
-
const retryOpts = {
|
|
409
|
-
retries: 2,
|
|
410
|
-
factor: 2,
|
|
411
|
-
minTimeout: 2000, // In milliseconds
|
|
412
|
-
};
|
|
413
|
-
return retry(async (bail, retryCount) => {
|
|
414
|
-
try {
|
|
415
|
-
return await apiCall();
|
|
416
|
-
} catch (err) {
|
|
417
|
-
const statusCode = get(err, [
|
|
418
|
-
"response",
|
|
419
|
-
"status",
|
|
420
|
-
]);
|
|
421
|
-
if (!this._isRetriableStatusCode(statusCode)) {
|
|
422
|
-
const errData = get(err, [
|
|
423
|
-
"response",
|
|
424
|
-
"data",
|
|
425
|
-
], {});
|
|
426
|
-
return bail(new Error(`
|
|
427
|
-
Unexpected error (status code: ${statusCode}):
|
|
428
|
-
${JSON.stringify(errData, null, 2)}
|
|
429
|
-
`));
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
console.log(`
|
|
433
|
-
[Attempt #${retryCount}] Temporary error: ${err.message}
|
|
434
|
-
`);
|
|
435
|
-
throw err;
|
|
436
|
-
}
|
|
437
|
-
}, retryOpts);
|
|
438
|
-
},
|
|
439
|
-
async _makeRequest({
|
|
440
|
-
$, config,
|
|
441
|
-
}) {
|
|
442
|
-
const token = {
|
|
443
|
-
key: this.$auth.oauth_access_token,
|
|
444
|
-
secret: this.$auth.oauth_refresh_token,
|
|
445
|
-
};
|
|
446
|
-
return this._withRetries(
|
|
447
|
-
() => axios($ ?? this, config, {
|
|
448
|
-
oauthSignerUri: this.$auth.oauth_signer_uri,
|
|
449
|
-
token,
|
|
450
|
-
}),
|
|
451
|
-
);
|
|
452
|
-
},
|
|
453
|
-
parseDate(dateStr) {
|
|
454
|
-
// More info on the parsing tokens:
|
|
455
|
-
// https://moment.github.io/luxon/docs/manual/parsing.html#table-of-tokens
|
|
456
|
-
return DateTime.fromFormat(dateStr, "EEE MMM dd HH:mm:ss ZZZ yyyy");
|
|
457
|
-
},
|
|
458
|
-
/**
|
|
459
|
-
* Enrich a Tweet object with ISO 8601 and timestamp (in milliseconds) representations of the
|
|
460
|
-
* `created_at` date/time, Tweet URL and user profile URL.
|
|
461
|
-
* @params {Object} tweet - An object representing a single Tweet as returned by Twitter's API
|
|
462
|
-
* @returns {Object} An enriched Tweet object is returned.
|
|
463
|
-
*/
|
|
464
|
-
enrichTweet(tweet) {
|
|
465
|
-
const parsedDate = this.parseDate(tweet.created_at);
|
|
466
|
-
tweet.created_at_timestamp = parsedDate.valueOf();
|
|
467
|
-
tweet.created_at_iso8601 = parsedDate.toISO();
|
|
468
|
-
tweet.url = `https://twitter.com/${tweet.user.screen_name}/statuses/${tweet.id_str}`;
|
|
469
|
-
if (tweet.user) tweet.user.profile_url = `https://twitter.com/${tweet.user.screen_name}/`;
|
|
470
|
-
return tweet;
|
|
471
|
-
},
|
|
472
|
-
async getFollowers(opts = {}) {
|
|
473
|
-
const {
|
|
474
|
-
$,
|
|
475
|
-
userId,
|
|
476
|
-
screenName,
|
|
477
|
-
includeUserEntities,
|
|
478
|
-
} = opts;
|
|
479
|
-
|
|
480
|
-
const params = {
|
|
481
|
-
user_id: userId,
|
|
482
|
-
screen_name: screenName,
|
|
483
|
-
include_user_entities: includeUserEntities,
|
|
484
|
-
};
|
|
485
|
-
const config = {
|
|
486
|
-
url: "https://api.twitter.com/1.1/followers/list.json",
|
|
487
|
-
params,
|
|
488
|
-
};
|
|
489
|
-
return (await this._makeRequest({
|
|
490
|
-
$,
|
|
491
|
-
config,
|
|
492
|
-
}));
|
|
493
|
-
},
|
|
494
|
-
async getPendingFollowers({
|
|
495
|
-
$, params,
|
|
496
|
-
}) {
|
|
497
|
-
const config = {
|
|
498
|
-
url: "https://api.twitter.com/1.1/friendships/incoming.json",
|
|
499
|
-
};
|
|
500
|
-
if (params && Object.keys(params).length !== 0) config.params = params;
|
|
501
|
-
return (await this._makeRequest({
|
|
502
|
-
$,
|
|
503
|
-
config,
|
|
504
|
-
}));
|
|
505
|
-
},
|
|
506
|
-
async *scanFollowerIds(screenName) {
|
|
507
|
-
const url = "https://api.twitter.com/1.1/followers/ids.json";
|
|
508
|
-
const baseParams = {
|
|
509
|
-
screen_name: screenName,
|
|
510
|
-
stringify_ids: true,
|
|
511
|
-
};
|
|
512
|
-
const config = {
|
|
513
|
-
url,
|
|
514
|
-
params: baseParams,
|
|
515
|
-
};
|
|
516
|
-
let {
|
|
517
|
-
ids,
|
|
518
|
-
next_cursor: nextCursor,
|
|
519
|
-
previous_cursor: prevCursor,
|
|
520
|
-
} = await this._makeRequest({
|
|
521
|
-
config,
|
|
522
|
-
});
|
|
523
|
-
while (nextCursor !== 0 || prevCursor === 0) {
|
|
524
|
-
for (const id of ids) {
|
|
525
|
-
yield id;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (nextCursor === 0) {
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const params = {
|
|
533
|
-
...baseParams,
|
|
534
|
-
cursor: nextCursor,
|
|
535
|
-
};
|
|
536
|
-
const config = {
|
|
537
|
-
url,
|
|
538
|
-
params,
|
|
539
|
-
};
|
|
540
|
-
({
|
|
541
|
-
ids,
|
|
542
|
-
next_cursor: nextCursor,
|
|
543
|
-
previous_cursor: prevCursor,
|
|
544
|
-
} = await this._makeRequest({
|
|
545
|
-
config,
|
|
546
|
-
}));
|
|
547
|
-
}
|
|
548
|
-
},
|
|
549
|
-
async getLists({
|
|
550
|
-
$, params,
|
|
551
|
-
}) {
|
|
552
|
-
const config = {
|
|
553
|
-
url: "https://api.twitter.com/1.1/lists/list.json",
|
|
554
|
-
params,
|
|
555
|
-
};
|
|
556
|
-
return (await this._makeRequest({
|
|
557
|
-
$,
|
|
558
|
-
config,
|
|
559
|
-
}));
|
|
560
|
-
},
|
|
561
|
-
async getPaginateListTweets(opts = {}) {
|
|
562
|
-
let allTweets = [];
|
|
563
|
-
let maxId;
|
|
564
|
-
const pageSize = 100;
|
|
565
|
-
do {
|
|
566
|
-
const response = await this.getListTweets({
|
|
567
|
-
...opts,
|
|
568
|
-
count: pageSize,
|
|
569
|
-
maxId,
|
|
570
|
-
});
|
|
571
|
-
const tweets = response.filter((r) => r.id != maxId);
|
|
572
|
-
if (!tweets || tweets.length < pageSize - 1) {
|
|
573
|
-
maxId = null;
|
|
574
|
-
} else {
|
|
575
|
-
const tweetWithMinId = tweets.reduce((prev, current) => {
|
|
576
|
-
return (prev.id < current.id) ?
|
|
577
|
-
prev :
|
|
578
|
-
current;
|
|
579
|
-
}, {});
|
|
580
|
-
maxId = tweetWithMinId?.id;
|
|
581
|
-
}
|
|
582
|
-
allTweets = allTweets.concat(tweets);
|
|
583
|
-
} while (maxId);
|
|
584
|
-
return allTweets;
|
|
585
|
-
},
|
|
586
|
-
async getListTweets(opts = {}) {
|
|
587
|
-
const {
|
|
588
|
-
$,
|
|
589
|
-
listId,
|
|
590
|
-
count,
|
|
591
|
-
maxId,
|
|
592
|
-
sinceId = "1",
|
|
593
|
-
includeEntities = false,
|
|
594
|
-
includeRetweets = false,
|
|
595
|
-
tweetMode = "extended",
|
|
596
|
-
} = opts;
|
|
597
|
-
const url = "https://api.twitter.com/1.1/lists/statuses.json";
|
|
598
|
-
const params = {
|
|
599
|
-
list_id: listId,
|
|
600
|
-
since_id: sinceId,
|
|
601
|
-
max_id: maxId,
|
|
602
|
-
count,
|
|
603
|
-
include_entities: includeEntities,
|
|
604
|
-
include_rts: includeRetweets,
|
|
605
|
-
tweet_mode: tweetMode,
|
|
606
|
-
};
|
|
607
|
-
const config = {
|
|
608
|
-
url,
|
|
609
|
-
params,
|
|
610
|
-
};
|
|
611
|
-
return await this._makeRequest({
|
|
612
|
-
$,
|
|
613
|
-
config,
|
|
614
|
-
});
|
|
615
|
-
},
|
|
616
|
-
async getLikedTweets(opts = {}) {
|
|
617
|
-
const {
|
|
618
|
-
$,
|
|
619
|
-
screenName,
|
|
620
|
-
count = 200,
|
|
621
|
-
tweetMode = "extended",
|
|
622
|
-
} = opts;
|
|
623
|
-
const config = {
|
|
624
|
-
url: "https://api.twitter.com/1.1/favorites/list.json",
|
|
625
|
-
params: {
|
|
626
|
-
screen_name: screenName,
|
|
627
|
-
count,
|
|
628
|
-
tweet_mode: tweetMode,
|
|
629
|
-
},
|
|
630
|
-
};
|
|
631
|
-
return (await this._makeRequest({
|
|
632
|
-
$,
|
|
633
|
-
config,
|
|
634
|
-
}));
|
|
635
|
-
},
|
|
636
|
-
async lookupUsers(opts = {}) {
|
|
637
|
-
const {
|
|
638
|
-
$,
|
|
639
|
-
userIdArray = [],
|
|
640
|
-
screenNameArray = [],
|
|
641
|
-
} = opts;
|
|
642
|
-
const config = {
|
|
643
|
-
url: "https://api.twitter.com/1.1/users/lookup.json",
|
|
644
|
-
params: {
|
|
645
|
-
user_id: userIdArray.join(),
|
|
646
|
-
screen_name: screenNameArray.join(),
|
|
647
|
-
},
|
|
648
|
-
};
|
|
649
|
-
return (await this._makeRequest({
|
|
650
|
-
$,
|
|
651
|
-
config,
|
|
652
|
-
}));
|
|
653
|
-
},
|
|
654
|
-
async search(opts = {}) {
|
|
655
|
-
const {
|
|
656
|
-
$,
|
|
657
|
-
q,
|
|
658
|
-
sinceId,
|
|
659
|
-
tweetMode,
|
|
660
|
-
count,
|
|
661
|
-
resultType,
|
|
662
|
-
locale,
|
|
663
|
-
geocode,
|
|
664
|
-
maxId,
|
|
665
|
-
} = opts;
|
|
666
|
-
const params = {
|
|
667
|
-
q,
|
|
668
|
-
since_id: sinceId,
|
|
669
|
-
max_id: maxId,
|
|
670
|
-
tweet_mode: tweetMode,
|
|
671
|
-
count,
|
|
672
|
-
result_type: resultType,
|
|
673
|
-
locale,
|
|
674
|
-
geocode,
|
|
675
|
-
};
|
|
676
|
-
const config = {
|
|
677
|
-
url: "https://api.twitter.com/1.1/search/tweets.json",
|
|
678
|
-
params,
|
|
679
|
-
};
|
|
680
|
-
return (await this._makeRequest({
|
|
681
|
-
$,
|
|
682
|
-
config,
|
|
683
|
-
}));
|
|
684
|
-
},
|
|
685
|
-
async getTrendLocations(opts = {}) {
|
|
686
|
-
const { $ } = opts;
|
|
687
|
-
const config = {
|
|
688
|
-
url: "https://api.twitter.com/1.1/trends/available.json",
|
|
689
|
-
};
|
|
690
|
-
return (await this._makeRequest({
|
|
691
|
-
$,
|
|
692
|
-
config,
|
|
693
|
-
}));
|
|
694
|
-
},
|
|
695
|
-
async getTrends(opts = {}) {
|
|
696
|
-
const {
|
|
697
|
-
$,
|
|
698
|
-
id = 1,
|
|
699
|
-
} = opts;
|
|
700
|
-
const config = {
|
|
701
|
-
url: "https://api.twitter.com/1.1/trends/place.json",
|
|
702
|
-
params: {
|
|
703
|
-
id,
|
|
704
|
-
},
|
|
705
|
-
};
|
|
706
|
-
return (await this._makeRequest({
|
|
707
|
-
$,
|
|
708
|
-
config,
|
|
709
|
-
}));
|
|
710
|
-
},
|
|
711
|
-
async getUserTimeline(opts = {}) {
|
|
712
|
-
const {
|
|
713
|
-
$,
|
|
714
|
-
screenName,
|
|
715
|
-
count = 100,
|
|
716
|
-
excludeReplies,
|
|
717
|
-
includeRts,
|
|
718
|
-
sinceId,
|
|
719
|
-
} = opts;
|
|
720
|
-
|
|
721
|
-
const params = {
|
|
722
|
-
screen_name: screenName,
|
|
723
|
-
count,
|
|
724
|
-
exclude_replies: excludeReplies,
|
|
725
|
-
include_rts: includeRts,
|
|
726
|
-
tweet_mode: "extended",
|
|
727
|
-
};
|
|
728
|
-
|
|
729
|
-
if (sinceId) {
|
|
730
|
-
params.since_id = sinceId;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
const config = {
|
|
734
|
-
url: "https://api.twitter.com/1.1/statuses/user_timeline.json",
|
|
735
|
-
method: "get",
|
|
736
|
-
params,
|
|
737
|
-
};
|
|
738
|
-
return (await this._makeRequest({
|
|
739
|
-
$,
|
|
740
|
-
config,
|
|
741
|
-
}));
|
|
742
|
-
},
|
|
743
|
-
async getMentionsTimeline(opts = {}) {
|
|
744
|
-
const {
|
|
745
|
-
$,
|
|
746
|
-
count,
|
|
747
|
-
includeEntities = false,
|
|
748
|
-
} = opts;
|
|
749
|
-
|
|
750
|
-
const params = {
|
|
751
|
-
count,
|
|
752
|
-
include_entities: includeEntities,
|
|
753
|
-
};
|
|
754
|
-
|
|
755
|
-
const config = {
|
|
756
|
-
url: "https://api.twitter.com/1.1/statuses/mentions_timeline.json",
|
|
757
|
-
method: "GET",
|
|
758
|
-
params,
|
|
759
|
-
};
|
|
760
|
-
return (await this._makeRequest({
|
|
761
|
-
$,
|
|
762
|
-
config,
|
|
763
|
-
}));
|
|
764
|
-
},
|
|
765
|
-
async getRetweets(opts = {}) {
|
|
766
|
-
const {
|
|
767
|
-
$,
|
|
768
|
-
id,
|
|
769
|
-
count = 100,
|
|
770
|
-
sinceId = "1",
|
|
771
|
-
} = opts;
|
|
772
|
-
|
|
773
|
-
const params = {
|
|
774
|
-
count,
|
|
775
|
-
trim_user: false,
|
|
776
|
-
since_id: sinceId,
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
const config = {
|
|
780
|
-
url: `https://api.twitter.com/1.1/statuses/retweets/${id}.json`,
|
|
781
|
-
method: "get",
|
|
782
|
-
params,
|
|
783
|
-
};
|
|
784
|
-
return (await this._makeRequest({
|
|
785
|
-
$,
|
|
786
|
-
config,
|
|
787
|
-
}));
|
|
788
|
-
},
|
|
789
|
-
async getRetweetsOfMe(opts = {}) {
|
|
790
|
-
const {
|
|
791
|
-
$,
|
|
792
|
-
count = 100,
|
|
793
|
-
sinceId = "1",
|
|
794
|
-
includeEntities = false,
|
|
795
|
-
includeUserEntities = false,
|
|
796
|
-
} = opts;
|
|
797
|
-
|
|
798
|
-
const params = {
|
|
799
|
-
count,
|
|
800
|
-
since_id: sinceId,
|
|
801
|
-
trim_user: false,
|
|
802
|
-
include_entities: includeEntities,
|
|
803
|
-
include_user_entities: includeUserEntities,
|
|
804
|
-
};
|
|
805
|
-
|
|
806
|
-
const config = {
|
|
807
|
-
url: "https://api.twitter.com/1.1/statuses/retweets_of_me.json",
|
|
808
|
-
method: "get",
|
|
809
|
-
params,
|
|
810
|
-
};
|
|
811
|
-
return (await this._makeRequest({
|
|
812
|
-
$,
|
|
813
|
-
config,
|
|
814
|
-
}));
|
|
815
|
-
},
|
|
816
|
-
async retweet({
|
|
817
|
-
$, tweetID,
|
|
818
|
-
}) {
|
|
819
|
-
const config = {
|
|
820
|
-
url: `https://api.twitter.com/1.1/statuses/retweet/${tweetID}.json`,
|
|
821
|
-
method: "post",
|
|
822
|
-
};
|
|
823
|
-
return (await this._makeRequest({
|
|
824
|
-
$,
|
|
825
|
-
config,
|
|
826
|
-
}));
|
|
827
|
-
},
|
|
828
|
-
async searchHelper(opts = {}) {
|
|
829
|
-
const tweets = [];
|
|
830
|
-
|
|
831
|
-
const {
|
|
832
|
-
$,
|
|
833
|
-
tweetMode = "extended",
|
|
834
|
-
resultType,
|
|
835
|
-
count = 100,
|
|
836
|
-
lang = [],
|
|
837
|
-
locale,
|
|
838
|
-
geocode,
|
|
839
|
-
enrichTweets = true,
|
|
840
|
-
includeReplies = "include",
|
|
841
|
-
includeRetweets = "include",
|
|
842
|
-
} = opts;
|
|
843
|
-
|
|
844
|
-
let {
|
|
845
|
-
q,
|
|
846
|
-
maxId,
|
|
847
|
-
sinceId,
|
|
848
|
-
} = opts;
|
|
849
|
-
let minId;
|
|
850
|
-
|
|
851
|
-
const langs = lang
|
|
852
|
-
.map((l) => `lang:${l}`)
|
|
853
|
-
.join(" OR ");
|
|
854
|
-
q = `${q} ${langs}`;
|
|
855
|
-
q = `${q} ${includeReplies}:replies`;
|
|
856
|
-
q = `${q} ${includeRetweets}:nativeretweets`;
|
|
857
|
-
|
|
858
|
-
const response = await this.search({
|
|
859
|
-
$,
|
|
860
|
-
q,
|
|
861
|
-
sinceId,
|
|
862
|
-
tweetMode,
|
|
863
|
-
count,
|
|
864
|
-
resultType,
|
|
865
|
-
locale,
|
|
866
|
-
geocode,
|
|
867
|
-
maxId,
|
|
868
|
-
});
|
|
869
|
-
|
|
870
|
-
if (!response) {
|
|
871
|
-
console.log("Last request was not successful.");
|
|
872
|
-
return {
|
|
873
|
-
statusCode: "Error",
|
|
874
|
-
};
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
for (const tweet of response.statuses) {
|
|
878
|
-
if ((!sinceId || (sinceId && tweet.id_str !== sinceId)) &&
|
|
879
|
-
(!maxId || (maxId && tweet.id_str !== maxId))) {
|
|
880
|
-
if (enrichTweets) {
|
|
881
|
-
tweets.push(this.enrichTweet(tweet));
|
|
882
|
-
} else {
|
|
883
|
-
tweets.push(tweet);
|
|
884
|
-
}
|
|
885
|
-
if (!maxId || tweet.id_str > maxId) {
|
|
886
|
-
maxId = tweet.id_str;
|
|
887
|
-
if (!minId) {
|
|
888
|
-
minId = maxId;
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
if (tweet.id_str < maxId) {
|
|
892
|
-
minId = tweet.id_str;
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
return {
|
|
898
|
-
tweets,
|
|
899
|
-
maxId,
|
|
900
|
-
minId,
|
|
901
|
-
count,
|
|
902
|
-
resultCount: response.statuses.length,
|
|
903
|
-
};
|
|
904
|
-
},
|
|
905
|
-
async paginatedSearch(opts = {}) {
|
|
906
|
-
const {
|
|
907
|
-
$,
|
|
908
|
-
count = 100,
|
|
909
|
-
q,
|
|
910
|
-
sinceId,
|
|
911
|
-
lang,
|
|
912
|
-
locale,
|
|
913
|
-
geocode,
|
|
914
|
-
resultType,
|
|
915
|
-
enrichTweets,
|
|
916
|
-
includeReplies,
|
|
917
|
-
includeRetweets,
|
|
918
|
-
limitFirstPage = true,
|
|
919
|
-
} = opts;
|
|
920
|
-
|
|
921
|
-
let {
|
|
922
|
-
maxId,
|
|
923
|
-
maxRequests = 1,
|
|
924
|
-
} = opts, totalRequests = 0;
|
|
925
|
-
|
|
926
|
-
const tweets = [];
|
|
927
|
-
|
|
928
|
-
if (limitFirstPage) {
|
|
929
|
-
maxRequests = 1;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
for (let request = 0; request < maxRequests; request++) {
|
|
933
|
-
const response = await this.searchHelper({
|
|
934
|
-
$,
|
|
935
|
-
count,
|
|
936
|
-
q,
|
|
937
|
-
sinceId,
|
|
938
|
-
maxId,
|
|
939
|
-
lang,
|
|
940
|
-
locale,
|
|
941
|
-
geocode,
|
|
942
|
-
resultType,
|
|
943
|
-
enrichTweets,
|
|
944
|
-
includeReplies,
|
|
945
|
-
includeRetweets,
|
|
946
|
-
});
|
|
947
|
-
|
|
948
|
-
// increment the count of requests to report out after all requests are complete
|
|
949
|
-
totalRequests++;
|
|
950
|
-
|
|
951
|
-
if (!response) {
|
|
952
|
-
break;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
tweets.push(...response.tweets);
|
|
956
|
-
|
|
957
|
-
//console.log(`resultCount: ${response.resultCount} count: ${response.count}`)
|
|
958
|
-
|
|
959
|
-
if (sinceId && totalRequests === maxRequests && response.resultCount === response.count) {
|
|
960
|
-
console.log("The last API request returned the maximum number of results. There may be additional tweets matching your search criteria. To return more tweets, increase the maximum number of API requests per execution.");
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
if (response.length === 0 || response.resultCount < response.count) {
|
|
964
|
-
break;
|
|
965
|
-
}
|
|
966
|
-
maxId = response.minId;
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
return tweets;
|
|
970
|
-
},
|
|
971
|
-
async verifyCredentials(opts = {}) {
|
|
972
|
-
const { $ } = opts;
|
|
973
|
-
const config = {
|
|
974
|
-
url: "https://api.twitter.com/1.1/account/verify_credentials.json",
|
|
975
|
-
};
|
|
976
|
-
return (await this._makeRequest({
|
|
977
|
-
$,
|
|
978
|
-
config,
|
|
979
|
-
}));
|
|
980
|
-
},
|
|
981
|
-
async createTweet({
|
|
982
|
-
$, params,
|
|
983
|
-
}) {
|
|
984
|
-
const config = {
|
|
985
|
-
url: "https://api.twitter.com/1.1/statuses/update.json",
|
|
986
|
-
method: "POST",
|
|
987
|
-
params,
|
|
988
|
-
};
|
|
989
|
-
return (await this._makeRequest({
|
|
990
|
-
$,
|
|
991
|
-
config,
|
|
992
|
-
}));
|
|
993
|
-
},
|
|
994
|
-
async getTweet(opts = {}) {
|
|
995
|
-
const {
|
|
996
|
-
$,
|
|
997
|
-
id,
|
|
998
|
-
includeEntities = false,
|
|
999
|
-
} = opts;
|
|
1000
|
-
const params = {
|
|
1001
|
-
id,
|
|
1002
|
-
include_entities: includeEntities,
|
|
1003
|
-
};
|
|
1004
|
-
const config = {
|
|
1005
|
-
url: "https://api.twitter.com/1.1/statuses/show.json",
|
|
1006
|
-
params,
|
|
1007
|
-
};
|
|
1008
|
-
return (await this._makeRequest({
|
|
1009
|
-
$,
|
|
1010
|
-
config,
|
|
1011
|
-
}));
|
|
1012
|
-
},
|
|
1013
|
-
async likeTweet(opts = {}) {
|
|
1014
|
-
const {
|
|
1015
|
-
$,
|
|
1016
|
-
id,
|
|
1017
|
-
includeEntities = false,
|
|
1018
|
-
} = opts;
|
|
1019
|
-
const params = {
|
|
1020
|
-
id,
|
|
1021
|
-
include_entities: includeEntities,
|
|
1022
|
-
};
|
|
1023
|
-
const config = {
|
|
1024
|
-
url: "https://api.twitter.com/1.1/favorites/create.json",
|
|
1025
|
-
method: "POST",
|
|
1026
|
-
params,
|
|
1027
|
-
};
|
|
1028
|
-
return (await this._makeRequest({
|
|
1029
|
-
$,
|
|
1030
|
-
config,
|
|
1031
|
-
}));
|
|
1032
|
-
},
|
|
1033
|
-
async unlikeTweet(opts = {}) {
|
|
1034
|
-
const {
|
|
1035
|
-
$,
|
|
1036
|
-
id,
|
|
1037
|
-
includeEntities = false,
|
|
1038
|
-
} = opts;
|
|
1039
|
-
const params = {
|
|
1040
|
-
id,
|
|
1041
|
-
include_entities: includeEntities,
|
|
1042
|
-
};
|
|
1043
|
-
const config = {
|
|
1044
|
-
url: "https://api.twitter.com/1.1/favorites/destroy.json",
|
|
1045
|
-
method: "POST",
|
|
1046
|
-
params,
|
|
1047
|
-
};
|
|
1048
|
-
return (await this._makeRequest({
|
|
1049
|
-
$,
|
|
1050
|
-
config,
|
|
1051
|
-
}));
|
|
1052
|
-
},
|
|
1053
|
-
async addUserToList(opts = {}) {
|
|
1054
|
-
const {
|
|
1055
|
-
$,
|
|
1056
|
-
slug,
|
|
1057
|
-
ownerScreenName,
|
|
1058
|
-
userId,
|
|
1059
|
-
screenName,
|
|
1060
|
-
} = opts;
|
|
1061
|
-
const params = {
|
|
1062
|
-
slug,
|
|
1063
|
-
owner_screen_name: ownerScreenName,
|
|
1064
|
-
user_id: userId,
|
|
1065
|
-
screen_name: screenName,
|
|
1066
|
-
};
|
|
1067
|
-
const config = {
|
|
1068
|
-
url: "https://api.twitter.com/1.1/lists/members/create.json",
|
|
1069
|
-
method: "POST",
|
|
1070
|
-
params,
|
|
1071
|
-
};
|
|
1072
|
-
return (await this._makeRequest({
|
|
1073
|
-
$,
|
|
1074
|
-
config,
|
|
1075
|
-
}));
|
|
1076
|
-
},
|
|
1077
|
-
async deleteTweet(opts = {}) {
|
|
1078
|
-
const {
|
|
1079
|
-
$,
|
|
1080
|
-
tweetID: id,
|
|
1081
|
-
trimUser,
|
|
1082
|
-
} = opts;
|
|
1083
|
-
const params = {
|
|
1084
|
-
id,
|
|
1085
|
-
trim_user: trimUser,
|
|
1086
|
-
};
|
|
1087
|
-
const config = {
|
|
1088
|
-
url: `https://api.twitter.com/1.1/statuses/destroy/${id}.json`,
|
|
1089
|
-
method: "POST",
|
|
1090
|
-
params,
|
|
1091
|
-
};
|
|
1092
|
-
return (await this._makeRequest({
|
|
1093
|
-
$,
|
|
1094
|
-
config,
|
|
1095
|
-
}));
|
|
1096
|
-
},
|
|
1097
|
-
async listDirectMessages({ $ }) {
|
|
1098
|
-
const config = {
|
|
1099
|
-
url: "https://api.twitter.com/1.1/direct_messages/events/list.json",
|
|
1100
|
-
};
|
|
1101
|
-
return (await this._makeRequest({
|
|
1102
|
-
$,
|
|
1103
|
-
config,
|
|
1104
|
-
}));
|
|
1105
|
-
},
|
|
1106
|
-
async followUser({
|
|
1107
|
-
params,
|
|
1108
|
-
$,
|
|
1109
|
-
}) {
|
|
1110
|
-
const config = {
|
|
1111
|
-
url: "https://api.twitter.com/1.1/friendships/create.json",
|
|
1112
|
-
method: "post",
|
|
1113
|
-
params,
|
|
1114
|
-
};
|
|
1115
|
-
return (await this._makeRequest({
|
|
1116
|
-
$,
|
|
1117
|
-
config,
|
|
1118
|
-
}));
|
|
1119
|
-
},
|
|
1120
|
-
async unfollowUser({
|
|
1121
|
-
params,
|
|
1122
|
-
$,
|
|
1123
|
-
}) {
|
|
1124
|
-
const config = {
|
|
1125
|
-
url: "https://api.twitter.com/1.1/friendships/destroy.json",
|
|
1126
|
-
method: "post",
|
|
1127
|
-
params,
|
|
1128
|
-
};
|
|
1129
|
-
return (await this._makeRequest({
|
|
1130
|
-
$,
|
|
1131
|
-
config,
|
|
1132
|
-
}));
|
|
1133
|
-
},
|
|
1134
|
-
async getUserFollows({
|
|
1135
|
-
params, $,
|
|
1136
|
-
}) {
|
|
1137
|
-
const config = {
|
|
1138
|
-
url: "https://api.twitter.com/1.1/friends/list.json",
|
|
1139
|
-
method: "GET",
|
|
1140
|
-
params,
|
|
1141
|
-
};
|
|
1142
|
-
return this._makeRequest({
|
|
1143
|
-
$,
|
|
1144
|
-
config,
|
|
1145
|
-
});
|
|
1146
|
-
},
|
|
1147
|
-
async uploadMedia({
|
|
1148
|
-
$, ...args
|
|
1149
|
-
}) {
|
|
1150
|
-
return this._makeRequest({
|
|
1151
|
-
$,
|
|
1152
|
-
config: {
|
|
1153
|
-
url: "https://upload.twitter.com/1.1/media/upload.json",
|
|
1154
|
-
method: "POST",
|
|
1155
|
-
...args,
|
|
1156
|
-
},
|
|
1157
|
-
});
|
|
1158
|
-
},
|
|
1159
|
-
webhooks: {},
|
|
1160
|
-
},
|
|
1161
|
-
};
|