@pipedream/twitter 0.3.2 → 0.3.5

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.
Files changed (55) hide show
  1. package/actions/add-user-to-list/add-user-to-list.mjs +62 -0
  2. package/actions/advanced-search/advanced-search.mjs +113 -0
  3. package/actions/common.mjs +29 -0
  4. package/actions/create-tweet/create-tweet.mjs +146 -0
  5. package/actions/delete-tweet/delete-tweet.mjs +42 -0
  6. package/actions/follow-user/follow-user.mjs +48 -0
  7. package/actions/get-tweet/get-tweet.mjs +42 -0
  8. package/actions/get-user/get-user.mjs +50 -0
  9. package/actions/like-tweet/like-tweet.mjs +42 -0
  10. package/actions/list-favorites/list-favorites.mjs +63 -0
  11. package/actions/list-followers/list-followers.mjs +67 -0
  12. package/actions/list-lists/list-lists.mjs +69 -0
  13. package/actions/list-mentions/list-mentions.mjs +55 -0
  14. package/actions/list-pending-followers/list-pending-followers.mjs +32 -0
  15. package/actions/list-retweets/list-retweets.mjs +54 -0
  16. package/actions/list-user-tweets/list-user-tweets.mjs +80 -0
  17. package/actions/retweet/retweet.mjs +27 -0
  18. package/actions/simple-search/simple-search.mjs +62 -0
  19. package/actions/simple-search-in-list/simple-search-in-list.mjs +48 -0
  20. package/actions/unfollow-user/unfollow-user.mjs +48 -0
  21. package/actions/unlike-tweet/unlike-tweet.mjs +40 -0
  22. package/package.json +21 -21
  23. package/readme.md +0 -4
  24. package/sources/common/followed.mjs +37 -0
  25. package/sources/common/followers.mjs +158 -0
  26. package/sources/common/tweets.mjs +154 -0
  27. package/sources/{language-codes.js → language-codes.mjs} +6 -2
  28. package/sources/my-liked-tweets/my-liked-tweets.mjs +29 -0
  29. package/sources/my-tweets/my-tweets.mjs +48 -0
  30. package/sources/new-follower-of-me/new-follower-of-me.mjs +69 -0
  31. package/sources/new-follower-of-user/new-follower-of-user.mjs +25 -0
  32. package/sources/new-list-followed/new-list-followed.mjs +24 -0
  33. package/sources/new-trends-by-geo/new-trends-by-geo.mjs +39 -0
  34. package/sources/new-tweet-in-list/new-tweet-in-list.mjs +49 -0
  35. package/sources/new-unfollower-of-me/{new-unfollower-of-me.js → new-unfollower-of-me.mjs} +5 -4
  36. package/sources/new-unfollower-of-user/new-unfollower-of-user.mjs +25 -0
  37. package/sources/new-user-followed/new-user-followed.mjs +25 -0
  38. package/sources/search-mentions/search-mentions.mjs +143 -0
  39. package/sources/tweets-liked-by-user/tweets-liked-by-user.mjs +37 -0
  40. package/sources/user-tweets/user-tweets.mjs +49 -0
  41. package/sources/watch-retweets-of-me/watch-retweets-of-me.mjs +36 -0
  42. package/sources/watch-retweets-of-my-tweet/watch-retweets-of-my-tweet.mjs +44 -0
  43. package/sources/watch-retweets-of-user-tweet/watch-retweets-of-user-tweet.mjs +34 -0
  44. package/twitter.app.mjs +1149 -0
  45. package/sources/common-followers.js +0 -99
  46. package/sources/my-liked-tweets/my-liked-tweets.js +0 -26
  47. package/sources/my-tweets/my-tweets.js +0 -83
  48. package/sources/new-follower-of-me/new-follower-of-me.js +0 -68
  49. package/sources/new-follower-of-user/new-follower-of-user.js +0 -69
  50. package/sources/new-trends-by-geo/new-trends-by-geo.js +0 -29
  51. package/sources/new-unfollower-of-user/new-unfollower-of-user.js +0 -22
  52. package/sources/search-mentions/search-mentions.js +0 -76
  53. package/sources/tweets-liked-by-user/tweets-liked-by-user.js +0 -27
  54. package/sources/user-tweets/user-tweets.js +0 -66
  55. package/twitter.app.js +0 -461
package/twitter.app.js DELETED
@@ -1,461 +0,0 @@
1
- const axios = require('axios')
2
- const querystring = require('querystring')
3
- const moment = require('moment')
4
-
5
- module.exports = {
6
- type: "app",
7
- app: "twitter",
8
- propDefinitions: {
9
- q: {
10
- type: "string",
11
- label: 'Search Term',
12
- 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).",
13
- },
14
- keyword_filter: {
15
- type: "string",
16
- label: 'Keywords',
17
- 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).",
18
- optional: true,
19
- },
20
- result_type: {
21
- type: "string",
22
- label: "Result Type",
23
- description: `Specifies the type of results you want to retrieve.`,
24
- optional: true,
25
- options: [
26
- { label: "Recent", value: "recent" },
27
- { label: "Popular", value: "popular" },
28
- { label: "Mixed", value: "mixed" },
29
- ],
30
- default: 'recent',
31
- },
32
- count: {
33
- type: "integer",
34
- min: 1,
35
- max: 100,
36
- label: "Count (advanced)",
37
- description: "The maximum number of tweets to return per API request (up to `100`)",
38
- optional: true,
39
- default: 100,
40
- },
41
- maxRequests: {
42
- type: "integer",
43
- min: 1,
44
- max: 180,
45
- label: "Max API Requests per Execution (advanced)",
46
- 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.",
47
- optional: true,
48
- default: 1,
49
- },
50
- from: {
51
- type: "string",
52
- label: "From",
53
- description: "The screen name of the user (e.g., `pipedream`)",
54
- },
55
- geocode: {
56
- type: "string",
57
- label: "Geocode",
58
- 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.",
59
- optional: true,
60
- },
61
- includeRetweets: {
62
- type: "string",
63
- label: "Retweets",
64
- description: "Select whether to `include`, `exclude` or `only` include retweets in emitted events.",
65
- optional: true,
66
- options: [
67
- { label: "Include", value: "include" },
68
- { label: "Exclude", value: "exclude" },
69
- { label: "Only include retweets", value: "only" },
70
- ],
71
- default: "include",
72
- },
73
- includeReplies: {
74
- type: "string",
75
- label: "Replies",
76
- description: "Select whether to `include`, `exclude` or `only` include replies in emitted events.",
77
- optional: true,
78
- options: [
79
- { label: "Include", value: "include" },
80
- { label: "Exclude", value: "exclude" },
81
- { label: "Only include replies", value: "only" },
82
- ],
83
- default: "include",
84
- },
85
- enrichTweets: {
86
- type: "boolean",
87
- label: "Enrich Tweets",
88
- description: "Enrich each tweet with epoch (milliseconds) and ISO8601 conversions of Twitter's `created_at` timestamp.",
89
- optional: true,
90
- default: true,
91
- },
92
- locale: {
93
- type: "string",
94
- label: "Locale",
95
- 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.",
96
- optional: true,
97
- },
98
- lang: {
99
- type: "string",
100
- label: "Language",
101
- description: "Restricts tweets to the given language. Language detection is best-effort.",
102
- optional: true,
103
- async options(context) {
104
- const { page } = context;
105
- if (page !== 0) {
106
- return {
107
- options: [],
108
- };
109
- }
110
-
111
- const isoLanguages = require('./sources/language-codes');
112
- return isoLanguages.map(isoLanguage => {
113
- const {
114
- English: language,
115
- alpha2: code,
116
- } = isoLanguage;
117
- return {
118
- label: `${language} (${code})`,
119
- value: code,
120
- };
121
- })
122
- }
123
- },
124
- screen_name: {
125
- type: "string",
126
- label: "Screen Name",
127
- description: "The screen name of the user (e.g., `pipedream`)"
128
- },
129
- trendLocation: {
130
- type: "string",
131
- label: "Location",
132
- async options(opts) {
133
- const trendLocations = await this.getTrendLocations()
134
- return trendLocations.map(location => {
135
- return { label: `${location.name}, ${location.countryCode} (${location.placeType.name})`, value: location.woeid }
136
- })
137
- },
138
- },
139
- },
140
- methods: {
141
- async _getAuthorizationHeader({ data, method, url }) {
142
- const requestData = {
143
- data,
144
- method,
145
- url,
146
- }
147
- const token = {
148
- key: this.$auth.oauth_access_token,
149
- secret: this.$auth.oauth_refresh_token,
150
- }
151
- return (await axios({
152
- method: 'POST',
153
- url: this.$auth.oauth_signer_uri,
154
- data: {
155
- requestData,
156
- token,
157
- }
158
- })).data
159
- },
160
- async _makeRequest(config, attempt = 0) {
161
- if (!config.headers) config.headers = {}
162
- if (config.params) {
163
- const query = querystring.stringify(config.params)
164
- delete config.params
165
- const sep = config.url.indexOf('?') === -1 ? '?' : '&'
166
- config.url += `${sep}${query}`
167
- config.url = config.url.replace('?&','?')
168
- }
169
- let authorization, count = 0
170
- const maxTries = 3
171
- while(true) {
172
- try {
173
- authorization = await this._getAuthorizationHeader(config)
174
- break
175
- } catch (err) {
176
- // handle exception
177
- if (++count == maxTries) {
178
- throw err
179
- }
180
- const milliseconds = 1000 * count
181
- await new Promise(resolve => setTimeout(resolve, milliseconds))
182
- }
183
- }
184
- config.headers.authorization = authorization
185
- return axios(config)
186
- },
187
- async getFollowers(screen_name) {
188
- return (await this._makeRequest({
189
- url: `https://api.twitter.com/1.1/followers/ids.json?`,
190
- params: {
191
- screen_name,
192
- stringify_ids: true,
193
- }
194
- })).data.ids
195
- },
196
- async *getAllFollowers(screenName) {
197
- const url = `https://api.twitter.com/1.1/followers/ids.json?`;
198
- const baseParams = {
199
- screen_name: screenName,
200
- stringify_ids: true,
201
- };
202
- const config = {
203
- url,
204
- params: baseParams,
205
- };
206
- const { data } = await this._makeRequest(config);
207
- let {
208
- ids,
209
- next_cursor: nextCursor,
210
- previous_cursor: prevCursor,
211
- } = data;
212
- while (nextCursor !== 0 || prevCursor === 0) {
213
- for (const id of ids) {
214
- yield id;
215
- }
216
-
217
- if (nextCursor === 0) {
218
- return;
219
- }
220
-
221
- const params = {
222
- ...baseParams,
223
- cursor: nextCursor,
224
- };
225
- const config = {
226
- url,
227
- params,
228
- };
229
- const { data } = await this._makeRequest(config);
230
- ({
231
- ids,
232
- next_cursor: nextCursor,
233
- previous_cursor: prevCursor,
234
- } = data);
235
- }
236
- },
237
- async getLikedTweets(opts = {}) {
238
- const {
239
- screen_name,
240
- count = 200,
241
- tweet_mode = 'extended',
242
- } = opts
243
- return (await this._makeRequest({
244
- url: `https://api.twitter.com/1.1/favorites/list.json`,
245
- params: {
246
- screen_name,
247
- count,
248
- tweet_mode,
249
- }
250
- })).data
251
- },
252
- async lookupUsers(userIdArray) {
253
- return (await this._makeRequest({
254
- url: `https://api.twitter.com/1.1/users/lookup.json`,
255
- params: {
256
- user_id: userIdArray.join(),
257
- }
258
- })).data
259
- },
260
- async search(opts = {}) {
261
- const { q, since_id, tweet_mode, count, result_type, lang, locale, geocode, max_id } = opts
262
- return (await this._makeRequest({
263
- url: `https://api.twitter.com/1.1/search/tweets.json`,
264
- params: {
265
- q,
266
- since_id,
267
- max_id,
268
- tweet_mode,
269
- count,
270
- result_type,
271
- lang,
272
- locale,
273
- geocode,
274
- }
275
- }))
276
- },
277
- async getTrendLocations() {
278
- return (await this._makeRequest({
279
- url: `https://api.twitter.com/1.1/trends/available.json`,
280
- })).data
281
- },
282
- async getTrends(opts = {}) {
283
- const {
284
- id = 1,
285
- } = opts
286
- return (await this._makeRequest({
287
- url: `https://api.twitter.com/1.1/trends/place.json`,
288
- params: {
289
- id,
290
- }
291
- })).data
292
- },
293
- async getUserTimeline(opts = {}) {
294
- const {
295
- screen_name,
296
- count = 100,
297
- exclude_replies,
298
- include_rts,
299
- since_id,
300
- } = opts
301
-
302
- const params = {
303
- screen_name,
304
- count,
305
- exclude_replies,
306
- include_rts,
307
- tweet_mode: 'extended',
308
- }
309
-
310
- if(since_id) {
311
- params.since_id = since_id
312
- }
313
-
314
- return (await this._makeRequest({
315
- url: `https://api.twitter.com/1.1/statuses/user_timeline.json`,
316
- method: 'get',
317
- params,
318
- })).data
319
- },
320
- async searchHelper(opts = {}) {
321
- const tweets = []
322
-
323
- const {
324
- tweet_mode = 'extended',
325
- result_type,
326
- count = 100,
327
- lang,
328
- locale,
329
- geocode,
330
- enrichTweets = true,
331
- includeReplies = true,
332
- includeRetweets = true,
333
- } = opts
334
-
335
- let { q, max_id, since_id } = opts
336
- let min_id
337
-
338
- if(includeReplies === 'exclude') {
339
- q = `${q} -filter:replies`
340
- } else if(includeReplies === 'only') {
341
- q = `${q} filter:replies`
342
- }
343
-
344
- if(includeRetweets === 'exclude') {
345
- q = `${q} -filter:nativeretweets`
346
- } else if(includeRetweets === 'only') {
347
- q = `${q} filter:nativeretweets`
348
- }
349
-
350
- const response = await this.search({ q, since_id, tweet_mode, count, result_type, lang, locale, geocode, max_id })
351
-
352
- if(!response) {
353
- console.log(`Last request was not successful.`)
354
- return {
355
- statusCode: "Error",
356
- }
357
- }
358
-
359
- for (let tweet of response.data.statuses) {
360
- if ((!since_id || (since_id && tweet.id_str !== since_id)) && (!max_id || (max_id && tweet.id_str !== max_id))) {
361
- if (enrichTweets) {
362
- tweet.created_at_timestamp = moment(tweet.created_at, 'ddd MMM DD HH:mm:ss Z YYYY').valueOf()
363
- tweet.created_at_iso8601 = moment(tweet.created_at, 'ddd MMM DD HH:mm:ss Z YYYY').toISOString()
364
- }
365
- tweets.push(tweet)
366
- if (!max_id || tweet.id_str > max_id) {
367
- max_id = tweet.id_str
368
- if(!min_id) {
369
- min_id = max_id
370
- }
371
- }
372
- if (tweet.id_str < max_id) {
373
- min_id = tweet.id_str
374
- }
375
- }
376
- }
377
-
378
- return {
379
- tweets,
380
- max_id,
381
- min_id,
382
- count,
383
- resultCount: response.data.statuses.length,
384
- statusCode: response.status,
385
- }
386
- },
387
- async paginatedSearch(opts = {}) {
388
- const {
389
- count = 100,
390
- q,
391
- since_id,
392
- lang,
393
- locale,
394
- geocode,
395
- result_type,
396
- enrichTweets,
397
- includeReplies,
398
- includeRetweets,
399
- limitFirstPage = true,
400
- } = opts
401
-
402
- let { max_id, maxRequests = 1 } = opts, totalRequests = 0
403
-
404
- const tweets = []
405
-
406
- if (limitFirstPage) {
407
- maxRequests = 1
408
- }
409
-
410
- //console.log(maxPages)
411
-
412
- for (let request = 0; request < maxRequests; request++) {
413
- const response = await this.searchHelper({
414
- count,
415
- q,
416
- since_id,
417
- max_id,
418
- lang,
419
- locale,
420
- geocode,
421
- result_type,
422
- enrichTweets,
423
- includeReplies,
424
- includeRetweets,
425
- })
426
-
427
- // increment the count of requests to report out after all requests are complete
428
- totalRequests++
429
-
430
- if (!response) {
431
- break
432
- }
433
-
434
- tweets.push(...response.tweets)
435
-
436
- //console.log(`resultCount: ${response.resultCount} count: ${response.count}`)
437
-
438
- if (since_id && totalRequests === maxRequests && response.resultCount === response.count) {
439
- 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.`)
440
- }
441
-
442
- if (response.length === 0 || response.resultCount < response.count) {
443
- break
444
- }
445
- max_id = response.min_id
446
- }
447
-
448
- console.log(`Made ${totalRequests} requests to the Twitter API and returned ${tweets.length} tweets.`)
449
-
450
- return tweets
451
- },
452
- async verifyCredentials() {
453
- return (await this._makeRequest({
454
- url: `https://api.twitter.com/1.1/account/verify_credentials.json`,
455
- })).data
456
- },
457
- webhooks: {
458
- // TODO
459
- },
460
- },
461
- }