@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.
Files changed (119) hide show
  1. package/README.md +20 -71
  2. package/dist/actions/add-user-to-list/add-user-to-list.d.ts +380 -0
  3. package/dist/actions/add-user-to-list/add-user-to-list.mjs +42 -0
  4. package/dist/actions/create-tweet/create-tweet.d.ts +163 -0
  5. package/dist/actions/create-tweet/create-tweet.mjs +78 -0
  6. package/dist/actions/delete-tweet/delete-tweet.d.ts +252 -0
  7. package/dist/actions/delete-tweet/delete-tweet.mjs +28 -0
  8. package/dist/actions/follow-user/follow-user.d.ts +255 -0
  9. package/dist/actions/follow-user/follow-user.mjs +37 -0
  10. package/dist/actions/get-tweet/get-tweet.d.ts +1006 -0
  11. package/dist/actions/get-tweet/get-tweet.mjs +35 -0
  12. package/dist/actions/get-user/get-user.d.ts +634 -0
  13. package/dist/actions/get-user/get-user.mjs +37 -0
  14. package/dist/actions/like-tweet/like-tweet.d.ts +252 -0
  15. package/dist/actions/like-tweet/like-tweet.mjs +30 -0
  16. package/dist/actions/list-favorites/list-favorites.d.ts +1138 -0
  17. package/dist/actions/list-favorites/list-favorites.mjs +52 -0
  18. package/dist/actions/list-followers/list-followers.d.ts +765 -0
  19. package/dist/actions/list-followers/list-followers.mjs +52 -0
  20. package/dist/actions/list-lists/list-lists.d.ts +762 -0
  21. package/dist/actions/list-lists/list-lists.mjs +52 -0
  22. package/dist/actions/list-mentions/list-mentions.d.ts +1136 -0
  23. package/dist/actions/list-mentions/list-mentions.mjs +52 -0
  24. package/dist/actions/list-user-tweets/list-user-tweets.d.ts +1138 -0
  25. package/dist/actions/list-user-tweets/list-user-tweets.mjs +52 -0
  26. package/dist/actions/retweet/retweet.d.ts +252 -0
  27. package/dist/actions/retweet/retweet.mjs +31 -0
  28. package/dist/actions/simple-search/simple-search.d.ts +1137 -0
  29. package/dist/actions/simple-search/simple-search.mjs +51 -0
  30. package/dist/actions/simple-search-in-list/simple-search-in-list.d.ts +1142 -0
  31. package/dist/actions/simple-search-in-list/simple-search-in-list.mjs +60 -0
  32. package/dist/actions/unfollow-user/unfollow-user.d.ts +255 -0
  33. package/dist/actions/unfollow-user/unfollow-user.mjs +33 -0
  34. package/dist/actions/unlike-tweet/unlike-tweet.d.ts +252 -0
  35. package/dist/actions/unlike-tweet/unlike-tweet.mjs +28 -0
  36. package/dist/app/twitter.app.d.ts +127 -0
  37. package/dist/app/twitter.app.mjs +341 -0
  38. package/dist/common/dataFields.d.ts +6 -0
  39. package/dist/common/dataFields.mjs +80 -0
  40. package/dist/common/expansions.d.ts +3 -0
  41. package/dist/common/expansions.mjs +17 -0
  42. package/dist/common/methods.d.ts +20 -0
  43. package/dist/common/methods.mjs +48 -0
  44. package/dist/common/propGroups.d.ts +1509 -0
  45. package/dist/common/propGroups.mjs +82 -0
  46. package/dist/common/types/fields.d.ts +18 -0
  47. package/dist/common/types/fields.mjs +1 -0
  48. package/dist/common/types/requestParams.d.ts +103 -0
  49. package/dist/common/types/requestParams.mjs +1 -0
  50. package/dist/common/types/responseSchemas.d.ts +42 -0
  51. package/dist/common/types/responseSchemas.mjs +1 -0
  52. package/dist/sources/common/base.d.ts +149 -0
  53. package/dist/sources/common/base.mjs +62 -0
  54. package/dist/sources/common/cacheUserId.d.ts +7 -0
  55. package/dist/sources/common/cacheUserId.mjs +18 -0
  56. package/dist/sources/common/getItemSummary.d.ts +4 -0
  57. package/dist/sources/common/getItemSummary.mjs +12 -0
  58. package/dist/sources/new-follower-of-user/new-follower-of-user.d.ts +650 -0
  59. package/dist/sources/new-follower-of-user/new-follower-of-user.mjs +49 -0
  60. package/dist/sources/new-list-followed/new-list-followed.d.ts +649 -0
  61. package/dist/sources/new-list-followed/new-list-followed.mjs +50 -0
  62. package/dist/sources/new-tweet-in-list/new-tweet-in-list.d.ts +1021 -0
  63. package/dist/sources/new-tweet-in-list/new-tweet-in-list.mjs +46 -0
  64. package/dist/sources/new-tweet-liked-by-user/new-tweet-liked-by-user.d.ts +1023 -0
  65. package/dist/sources/new-tweet-liked-by-user/new-tweet-liked-by-user.mjs +49 -0
  66. package/dist/sources/new-tweet-posted-by-user/new-tweet-posted-by-user.d.ts +1023 -0
  67. package/dist/sources/new-tweet-posted-by-user/new-tweet-posted-by-user.mjs +49 -0
  68. package/dist/sources/new-tweet-posted-matching-query/new-tweet-posted-matching-query.d.ts +1021 -0
  69. package/dist/sources/new-tweet-posted-matching-query/new-tweet-posted-matching-query.mjs +51 -0
  70. package/dist/sources/new-unfollower-of-user/new-unfollower-of-user.d.ts +273 -0
  71. package/dist/sources/new-unfollower-of-user/new-unfollower-of-user.mjs +75 -0
  72. package/dist/sources/new-user-followed/new-user-followed.d.ts +649 -0
  73. package/dist/sources/new-user-followed/new-user-followed.mjs +50 -0
  74. package/dist/tsconfig.tsbuildinfo +1 -0
  75. package/package.json +10 -13
  76. package/actions/add-user-to-list/add-user-to-list.mjs +0 -62
  77. package/actions/advanced-search/advanced-search.mjs +0 -113
  78. package/actions/common.mjs +0 -29
  79. package/actions/create-tweet/create-tweet.mjs +0 -146
  80. package/actions/delete-tweet/delete-tweet.mjs +0 -42
  81. package/actions/follow-user/follow-user.mjs +0 -48
  82. package/actions/get-tweet/get-tweet.mjs +0 -42
  83. package/actions/get-user/get-user.mjs +0 -50
  84. package/actions/like-tweet/like-tweet.mjs +0 -42
  85. package/actions/list-favorites/list-favorites.mjs +0 -63
  86. package/actions/list-followers/list-followers.mjs +0 -67
  87. package/actions/list-lists/list-lists.mjs +0 -69
  88. package/actions/list-mentions/list-mentions.mjs +0 -55
  89. package/actions/list-pending-followers/list-pending-followers.mjs +0 -32
  90. package/actions/list-retweets/list-retweets.mjs +0 -54
  91. package/actions/list-user-tweets/list-user-tweets.mjs +0 -80
  92. package/actions/retweet/retweet.mjs +0 -27
  93. package/actions/simple-search/simple-search.mjs +0 -62
  94. package/actions/simple-search-in-list/simple-search-in-list.mjs +0 -48
  95. package/actions/unfollow-user/unfollow-user.mjs +0 -48
  96. package/actions/unlike-tweet/unlike-tweet.mjs +0 -40
  97. package/actions/upload-media/upload-media.mjs +0 -114
  98. package/old.md +0 -169
  99. package/sources/common/followed.mjs +0 -38
  100. package/sources/common/followers.mjs +0 -159
  101. package/sources/common/tweets.mjs +0 -155
  102. package/sources/language-codes.mjs +0 -742
  103. package/sources/my-liked-tweets/my-liked-tweets.mjs +0 -30
  104. package/sources/my-tweets/my-tweets.mjs +0 -48
  105. package/sources/new-follower-of-me/new-follower-of-me.mjs +0 -69
  106. package/sources/new-follower-of-user/new-follower-of-user.mjs +0 -25
  107. package/sources/new-list-followed/new-list-followed.mjs +0 -24
  108. package/sources/new-trends-by-geo/new-trends-by-geo.mjs +0 -40
  109. package/sources/new-tweet-in-list/new-tweet-in-list.mjs +0 -49
  110. package/sources/new-unfollower-of-me/new-unfollower-of-me.mjs +0 -16
  111. package/sources/new-unfollower-of-user/new-unfollower-of-user.mjs +0 -25
  112. package/sources/new-user-followed/new-user-followed.mjs +0 -25
  113. package/sources/search-mentions/search-mentions.mjs +0 -144
  114. package/sources/tweets-liked-by-user/tweets-liked-by-user.mjs +0 -38
  115. package/sources/user-tweets/user-tweets.mjs +0 -49
  116. package/sources/watch-retweets-of-me/watch-retweets-of-me.mjs +0 -36
  117. package/sources/watch-retweets-of-my-tweet/watch-retweets-of-my-tweet.mjs +0 -44
  118. package/sources/watch-retweets-of-user-tweet/watch-retweets-of-user-tweet.mjs +0 -34
  119. package/twitter.app.mjs +0 -1161
@@ -1,40 +0,0 @@
1
- import twitter from "../../twitter.app.mjs";
2
-
3
- export default {
4
- key: "twitter-unlike-tweet",
5
- name: "Unike Tweet",
6
- description: "Unike the tweet specified specified in the ID parameter. [See the docs here](https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-favorites-destroy)",
7
- version: "0.0.2",
8
- type: "action",
9
- props: {
10
- twitter,
11
- id: {
12
- propDefinition: [
13
- twitter,
14
- "tweetID",
15
- ],
16
- },
17
- includeEntities: {
18
- propDefinition: [
19
- twitter,
20
- "includeEntities",
21
- ],
22
- },
23
- },
24
- async run({ $ }) {
25
- const {
26
- id,
27
- includeEntities,
28
- } = this;
29
-
30
- const params = {
31
- $,
32
- id,
33
- includeEntities,
34
- };
35
-
36
- const res = this.twitter.unlikeTweet(params);
37
- $.export("$summary", "Successfully unliked tweet");
38
- return res;
39
- },
40
- };
@@ -1,114 +0,0 @@
1
- import twitter from "../../twitter.app.mjs";
2
- import fs from "fs";
3
- import mime from "mime";
4
-
5
- export default {
6
- key: "twitter-upload-media",
7
- name: "Upload Media",
8
- description: "Upload images or other media types to Twitter. Returns a `media_id_string` to be used with the Create Tweet action. [See the docs here](https://developer.twitter.com/en/docs/tutorials/uploading-media)",
9
- version: "0.0.2",
10
- type: "action",
11
- props: {
12
- twitter,
13
- file: {
14
- type: "string",
15
- label: "File",
16
- description: "The file to upload to Twitter, please provide a file from `/tmp`. To upload a file to `/tmp` folder, please follow the doc [here](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp)",
17
- },
18
- mediaType: {
19
- type: "string",
20
- label: "Media Type",
21
- description: "The MIME type of the media being uploaded",
22
- options() {
23
- return Object.values(mime._types);
24
- },
25
- },
26
- mediaCategory: {
27
- type: "string",
28
- label: "Media Category",
29
- description: "The category that represents how the media will be used",
30
- options: [
31
- "amplify_video",
32
- "tweet_gif",
33
- "tweet_image",
34
- "tweet_video",
35
- ],
36
- },
37
- },
38
- async run({ $ }) {
39
- // INIT
40
- const fileContent = fs.readFileSync(this.file, {
41
- encoding: "base64",
42
- });
43
- const fileSize = (fs.statSync(this.file)).size;
44
- const params = {
45
- command: "INIT",
46
- total_bytes: fileSize,
47
- media_type: this.mediaType,
48
- additional_owners: this.twitter.$auth.oauth_uid,
49
- };
50
- if (this.mediaCategory) {
51
- params.media_category = this.mediaCategory;
52
- }
53
- const { media_id_string: mediaId } = await this.twitter.uploadMedia({
54
- params,
55
- $,
56
- });
57
-
58
- // APPEND
59
- const size = 9000;
60
- const numSegments = fileContent.length / size;
61
- let segment = 0;
62
- let startIndex = 0;
63
- let endIndex = startIndex + size;
64
- while (segment <= numSegments) {
65
- const chunk = fileContent.substring(startIndex, endIndex);
66
- const params = {
67
- command: "APPEND",
68
- media_id: mediaId,
69
- media_data: chunk,
70
- segment_index: segment,
71
- };
72
- await this.twitter.uploadMedia({
73
- params,
74
- $,
75
- });
76
- segment++;
77
- startIndex += size;
78
- endIndex += size;
79
- }
80
-
81
- // FINALIZE
82
- let response;
83
- response = await this.twitter.uploadMedia({
84
- params: {
85
- command: "FINALIZE",
86
- media_id: mediaId,
87
- },
88
- $,
89
- });
90
-
91
- // STATUS
92
- while (this.mediaCategory?.includes("video")) {
93
- response = await this.twitter.uploadMedia({
94
- params: {
95
- command: "STATUS",
96
- media_id: mediaId,
97
- },
98
- method: "GET",
99
- $,
100
- });
101
- const { processing_info: info } = response;
102
- if (info?.error) {
103
- throw new Error(JSON.stringify(info.error));
104
- }
105
- if (info?.state === "succeeded") {
106
- break;
107
- }
108
- setTimeout(() => {}, info.check_after_secs * 1000);
109
- }
110
-
111
- response && $.export("$summary", `Successfully uploaded media with Media ID ${mediaId}`);
112
- return response;
113
- },
114
- };
package/old.md DELETED
@@ -1,169 +0,0 @@
1
- <p align="center">
2
-
3
- <img width="124" height="100" src="/images/twitter/TwitterLogo.png">
4
- </p>
5
- <h1 align="center"><strong>Twitter Workflow Automation</strong></h1>
6
-
7
-
8
- <p align="center">Patterns for processing streams of tweets and interacting with the Twitter API</p>
9
-
10
- <p align="center">
11
- <a href="#example-workflows"><img width="30%" src="/images/twitter/ExampleWorkflow.png" alt="Getting Started"></a>
12
- <a href="#twitter-event-sources"><img width="30%" src="/images/twitter/TwitterEventSources.png" alt="Example Worksflows"></a>
13
- <a href="#sse-and-rest-apis"><img width="30%" src="/images/twitter/SSE_RESTAPI.png" alt="SSE + REST API"></a>
14
- </p>
15
-
16
- &nbsp;&nbsp;
17
-
18
- ## Example Workflows
19
- Workflows are linear sequences of steps — just Node.js code —hosted and run by Pipedream.
20
-
21
- **You can copy the workflows below and run them in your Pipedream account** [**for free**](https://docs.pipedream.com/pricing/ ). They run code on new tweets and interact with the Twitter API in creative ways. You can modify or extend them in any way you'd like, [**running your own Node code**](https://docs.pipedream.com/workflows/steps/code/) or using [**pre-built functions**](https://docs.pipedream.com/workflows/steps/actions/) to connect to [**200+ integrated apps**](https://docs.pipedream.com/apps/all-apps/).
22
-
23
- On copy, you'll be asked to create a [**Twitter event source**](#twitter-event-sources) that triggers your workflow on new tweets matching your target search.
24
-
25
- A single Twitter source can trigger multiple workflows. If you already created a source you want to use as a trigger, click **Select Another Trigger** near the bottom-left of the source selector.
26
-
27
- <p align="center">
28
- <a href="https://pipedream.com/@dylan/twitter-to-email-p_zACral/readme"><img alt="Twitter to Email" src="/images/twitter/T2Em.png" width="45%"></a>
29
- <a href="https://pipedream.com/@dylan/send-an-http-post-request-on-new-tweets-p_6lCRoN/readme"><img alt="Twitter to Webhook" src="/images/twitter/T2We.png" width="45%"></a>
30
- </p>
31
- <p align="center">
32
- <a href="https://pipedream.com/@dylan/twitter-to-aws-sqs-p_vQCraZ/readme"><img alt="Twitter to AWS SQS" src="/images/twitter/T2AS.png" width="45%"></a>
33
- <a href="https://pipedream.com/@dylan/twitter-to-aws-eventbridge-event-bus-p_ZJCWpg/readme"><img alt="Twitter to AWS EventBridge" src="/images/twitter/T2AE.png" width="45%"></a>
34
- </p>
35
- <p align="center">
36
- <a href="https://pipedream.com/@dylan/twitter-to-aws-lambda-p_wOCAdP/readme"><img alt="Twitter to AWS Lambda" src="/images/twitter/T2AL.png" width="45%"></a>
37
- <a href="https://pipedream.com/@dylan/twitter-to-telegram-p_QPC8JP/readme"><img alt="Twitter to Telegram" src="/images/twitter/T2Te.png" width="45%"></a>
38
- </p>
39
- <p align="center">
40
- <a href="https://pipedream.com/@pravin/twitter-mentions-slack-p_dDCA5e/edit"><img alt="Twitter to Slack" src="/images/twitter/T2Sl.png" width="45%"></a>
41
- <a href="https://pipedream.com/@dylan/twitter-to-discord-p_MOCQ9Y/readme"><img alt="Twitter to Discord" src="/images/twitter/T2Ti.png" width="45%"></a>
42
- </p>
43
- <p align="center">
44
- <a href="https://pipedream.com/@dylan/twitter-to-s3-p_KwCZGA/readme"><img alt="Twitter to S3" src="/images/twitter/T2S3.png" width="45%"></a>
45
- <a href="https://pipedream.com/@dylan/twitter-to-pipedream-sql-service-p_brCMA9/readme"><img alt="Twitter to SQ:" src="/images/twitter/T2Sq.png" width="45%"></a>
46
- </p>
47
-
48
- &nbsp;&nbsp;
49
-
50
- ## Twitter Event Sources
51
-
52
- Pipedream [**event sources**](https://docs.pipedream.com/event-sources/) emit Twitter events in real time: tweets, follows, likes, and more. Sources can trigger [**Pipedream workflows**](#example-workflows), and can be accessed via [**SSE or REST APIs**](#apis).
53
-
54
- Click on a source below to get started.
55
-
56
- <p align="center">
57
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fsearch-twitter.js&amp;app=twitter"><img alt="Search Mention" src="/images/twitter/SM.png" width="45%"></a>
58
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fmy-tweets.js&amp;app=twitter"><img alt="My Tweets" src="/images/twitter/MT.png" width="45%"></a>
59
- </p>
60
- <p align="center">
61
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fnew-follower-of-user.js&amp;app=twitter"><img alt="New Follower for User" src="/images/twitter/NFfU.png" width="45%"></a>
62
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fnew-follower-of-me.js&amp;app=twitter"><img alt="My New Followers" src="/images/twitter/MNF.png" width="45%"></a>
63
- </p>
64
- <p align="center">
65
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fmy-liked-tweets.js&amp;app=twitter"><img alt="My Liked Tweets" src="/images/twitter/MLT.png" width="45%"></a>
66
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Ftweets-liked-by-user.js&amp;app=twitter"><img alt="Tweets Liked by User" src="/images/twitter/TLbU.png" width="45%"></a>
67
- </p>
68
- <p align="center">
69
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fuser-tweets.js&amp;app=twitter"><img alt="New Tweets from User" src="/images/twitter/NTfU.png" width="45%"></a>
70
- <a href="https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fnew-trends-by-geo.js&amp;app=twitter"><img alt="New Trends by Geo" src="/images/twitter/NTbG.png" width="45%"></a>
71
- </p>
72
-
73
- Let's see how sources work with an end-to-end example:**running code on new mentions**.
74
-
75
- Most Twitter bots react to other tweets. For example, you might want to reply to a user with a specific message every time they mention you. Or you may want to store every tweet with a specific hashtag in an Amazon S3 bucket.
76
-
77
- When you create a Twitter bot, you typically have to sign up for a Twitter developer account, create your own app, host it somewhere, and run code to poll for new tweets. This is a means to an end:**all you really want to do is run code on new tweets**.
78
-
79
- ```js
80
- // Don't care how I get tweets
81
- for (const tweet of tweets) {
82
- // Just want to run code
83
- }
84
- ```
85
-
86
- Pipedream lets you create a stream of tweets you can process programmatically in seconds, avoiding the app setup entirely. These are called [**event sources**](https://docs.pipedream.com/event-sources/).
87
-
88
- Pipedream runs the code to poll for new tweets matching your search terms, emitting them as events you can run code on.
89
-
90
- <p align="center">
91
- <img alt="pipeDream" src="/images/twitter/TwitterPipeDream.png">
92
- </p>
93
-
94
- Then, you can immediately process those tweets in a few different ways:
95
-
96
- + Trigger a Pipedream workflow for each tweet, running hosted Node.js code in real time
97
- + Subscribe to a private SSE stream, which also publishes tweets in real time
98
- + Access tweets in batch using Pipedream's REST API
99
-
100
- To get started, [**create a new Twitter search source in the Pipedream UI**](https://pipedream.com/sources?action=create&amp;url=https%3A%2F%2Fgithub.com%2FPipedreamHQ%2Fpipedream%2Fblob%2Fmaster%2Fcomponents%2Ftwitter%2Fsearch-twitter.js&amp;app=twitter&amp;src=twitter.pipedream.com). Name the source, connect your Twitter account, and add your search term:
101
-
102
- <p align="center">
103
- <kbd><img alt="Twitter Source in Pipedream UI" width="700" src="/images/twitter/twitter-source-in-ui.png"></kbd>
104
- </p>
105
-
106
- You can also visit [**https://pipedream.com/sources**](https://pipedream.com/sources) and click the **Create Source** button, then choose the **twitter/twitter-search.js** source from the modal that appears.
107
-
108
- Then, you can trigger a [**Pipedream workflow**](https://pipedream.com/new) — a serverless Node.js script — on every tweet:
109
-
110
- <p align="center">
111
- <kbd><img alt="New workflow source" width="550" src="/images/twitter/new-workflow-source.png"></kbd>
112
- </p>
113
-
114
-
115
- They should work as is, but you can modify them in any way. For example, you can add a step to [**run any Node.js code**](https://docs.pipedream.com/workflows/steps/code/) or use [**pre-built functions**](https://docs.pipedream.com/workflows/steps/actions/) to send data to other destinations.
116
-
117
-
118
- &nbsp;&nbsp;
119
-
120
- ## SSE and REST APIs
121
-
122
- Pipedream provides two other interfaces for accessing events produced by sources:
123
-
124
- + A private SSE stream specific to your source
125
- + A REST API
126
-
127
- This way, you can run an event source in Pipedream but access its events in your own application.
128
-
129
- ### SSE
130
-
131
- SSE —[**Server-sent events**](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)—defines a spec for how servers can send events directly to clients that subscribe to those events, similar to [**WebSockets**](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) and related server-to-client push technologies. If you listen for new items using SSE, **you can run any code in your own application, in real time, as soon as those items are added to the feed.**
132
-
133
- Streams are private by default. You authenticate by passing your Pipedream API key in the Authorization header:
134
-
135
- ```js
136
- $ curl -H "Authorization: Bearer API_KEY" \
137
-
138
- https://api.pipedream.com/sources/SOURCE_ID/sse
139
- ```
140
-
141
- [**See the Pipedream SSE docs**](https://docs.pipedream.com/api/sse) for more information on authentication, example Node code, and other details on the interface.
142
-
143
- ### REST API
144
-
145
- If you prefer to process tweets in batch, you can fetch them using [**Pipedream's REST API**](https://docs.pipedream.com/api/rest/):
146
-
147
- ```js
148
- $ curl -H "Authorization: Bearer API_KEY" \
149
-
150
- https://api.pipedream.com/v1/sources/SOURCE_ID/event_summaries?limit=1
151
- ```
152
-
153
- Note the?limit=1query string. You can vary the number of events returned (most recent first) by setting this param.
154
-
155
- Please [**reach out**](https://docs.pipedream.com/support/) with any questions or feedback. We're happy to add other Twitter-specific developer resources to this list, and we'd love to hear what can be improved about event sources or the example workflows.
156
-
157
- &nbsp;&nbsp;
158
-
159
- ___
160
-
161
- <p align="center">
162
- Pipedream, Inc. — San Francisco, CA
163
- </p>
164
- <p align="center">
165
- <a href="https://twitter.com/PipedreamHQ">Twitter</a> | <a href="https://pipedream.com/community">Community</a> | <a href="https://docs.pipedream.com/">Docs</a> | <a href="https://pipedream.com/terms">Terms</a> |
166
- <a href="https://pipedream.com/privacy">Privacy</a>
167
- </p>
168
-
169
- ___
@@ -1,38 +0,0 @@
1
- import twitter from "../../twitter.app.mjs";
2
- import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3
-
4
- export default {
5
- props: {
6
- twitter,
7
- db: "$.service.db",
8
- timer: {
9
- label: "Polling interval",
10
- description: "Pipedream will poll the Twitter API on this schedule",
11
- type: "$.interface.timer",
12
- default: {
13
- intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
14
- },
15
- },
16
- },
17
- methods: {
18
- _getPreviousIds() {
19
- return this.db.get("previousIds") || [];
20
- },
21
- _setPreviousIds(previousIds) {
22
- this.db.set("previousIds", previousIds);
23
- },
24
- },
25
- async run() {
26
- const previousIds = this._getPreviousIds();
27
- const followedItems = await this.getFollowed();
28
- for (const item of followedItems.reverse()) {
29
- if (previousIds.includes(item.id)) {
30
- continue;
31
- }
32
- previousIds.push(item.id);
33
- const meta = this.generateMeta(item);
34
- this.$emit(item, meta);
35
- }
36
- this._setPreviousIds(previousIds);
37
- },
38
- };
@@ -1,159 +0,0 @@
1
- import twitter from "../../twitter.app.mjs";
2
- import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3
-
4
- export default {
5
- props: {
6
- db: "$.service.db",
7
- twitter,
8
- timer: {
9
- label: "Polling interval",
10
- description: "Pipedream will poll the Twitter API on this schedule",
11
- type: "$.interface.timer",
12
- default: {
13
- intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
14
- },
15
- },
16
- },
17
- hooks: {
18
- async activate() {
19
- await this._provisionFollowersCache();
20
- },
21
- },
22
- deactivate() {
23
- this._clearFollowersCache();
24
- },
25
- methods: {
26
- /**
27
- * This method returns the size of the internal cache used by the event
28
- * source to keep track of the latest Twitter followers of the corresponding
29
- * account.
30
- *
31
- * The size represents the maximum amount of entries/ID's that will be
32
- * cached at any given time (or 0 for unlimited). Keep in mind that the
33
- * Pipedream platform itself imposes size limits as well in terms of DB
34
- * usage.
35
- *
36
- * @returns The maximum amount of Twitter followers entries to be cached at
37
- * any given moment (or 0 for unlimited).
38
- */
39
- getFollowersCacheSize() {
40
- return 0;
41
- },
42
- getScreenName() {
43
- // When screen name is not explicitly provided, the Twitter API defaults
44
- // it to the user making the API request
45
- return undefined;
46
- },
47
- /**
48
- * This function provides the list of relevant, follower-related, user ID's
49
- * that are used by the event source to emit events. How each event source
50
- * that implements it depends on the purpose of the event source itself. For
51
- * example, an event source that emits an event for every new follower will
52
- * implement this function in such a way that its result is a list of user
53
- * ID's for each new follower detected.
54
- *
55
- * @returns the list of relevant user ID's for this event source to process
56
- */
57
- getRelevantIds() {
58
- return [];
59
- },
60
- generateMeta(data) {
61
- const {
62
- timestamp,
63
- user,
64
- } = data;
65
- const {
66
- id_str: id,
67
- screen_name: summary,
68
- } = user;
69
- // Event timestamp is expressed in seconds, whereas Javascript timestamps
70
- // are expressed in milliseconds
71
- const ts = timestamp * 1000;
72
- return {
73
- id,
74
- summary,
75
- ts,
76
- };
77
- },
78
- _clearFollowersCache() {
79
- this.setFollowersCache([]);
80
- },
81
- async _provisionFollowersCache() {
82
- const screenName = this.getScreenName();
83
- const followerIdsGen = this.twitter.scanFollowerIds(screenName);
84
- const maxFollowerListSize = Math.max(this.getFollowersCacheSize(), 0);
85
- const result = [];
86
- for await (const id of followerIdsGen) {
87
- if (maxFollowerListSize !== 0 && maxFollowerListSize === result.length) {
88
- break;
89
- }
90
-
91
- result.push(id);
92
- }
93
-
94
- this.setFollowersCache(result);
95
- return result;
96
- },
97
- getFollowersCache() {
98
- return this.db.get("followers");
99
- },
100
- setFollowersCache(followers) {
101
- const followersCacheSize = Math.max(this.getFollowersCacheSize(), 0);
102
- const trimmedFollowers = followersCacheSize !== 0
103
- ? followers.slice(0, followersCacheSize)
104
- : followers;
105
- this.db.set("followers", trimmedFollowers);
106
- console.log(`
107
- Updated followers cache: ${trimmedFollowers.length} records
108
- `);
109
- },
110
- /**
111
- * This generator method scans the list of Twitter followers until it finds
112
- * the ID of a follower that was already processed.
113
- *
114
- * @param {string[]} processedFollowerIds a list of the ID's of the most
115
- * recent Twitter followers processed by the event source
116
- * @yields the ID of a new Twitter follower
117
- */
118
- async *scanNewFollowers(processedFollowerIds = []) {
119
- const processeedFollowerIdsSet = new Set(processedFollowerIds);
120
- const screenName = this.getScreenName();
121
- const followerIdsGen = this.twitter.scanFollowerIds(screenName);
122
- for await (const id of followerIdsGen) {
123
- if (processeedFollowerIdsSet.has(id)) {
124
- break;
125
- }
126
- yield id;
127
- }
128
- },
129
- async getUnfollowers() {
130
- const prevFollowers = this.getFollowersCache();
131
- const currFollowers = await this._provisionFollowersCache();
132
- const currFollowersSet = new Set(currFollowers);
133
- return prevFollowers.filter((pf) => !currFollowersSet.has(pf));
134
- },
135
- },
136
- async run(event) {
137
- const { timestamp } = event;
138
- const relevantIds = await this.getRelevantIds();
139
- if (relevantIds.length <= 0) {
140
- console.log(`
141
- No changes in followers data for this event source to emit a new event
142
- `);
143
- return;
144
- }
145
-
146
- const users = await this.twitter.lookupUsers({
147
- userIdArray: relevantIds,
148
- });
149
- users.forEach((user) => {
150
- const data = {
151
- timestamp,
152
- user,
153
- };
154
- user.profile_url = `https://twitter.com/${user.screen_name}/`;
155
- const meta = this.generateMeta(data);
156
- this.$emit(user, meta);
157
- });
158
- },
159
- };
@@ -1,155 +0,0 @@
1
- import twitter from "../../twitter.app.mjs";
2
- import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3
-
4
- export default {
5
- props: {
6
- db: "$.service.db",
7
- twitter,
8
- count: {
9
- propDefinition: [
10
- twitter,
11
- "count",
12
- ],
13
- },
14
- maxRequests: {
15
- propDefinition: [
16
- twitter,
17
- "maxRequests",
18
- ],
19
- },
20
- timer: {
21
- label: "Polling interval",
22
- description: "Pipedream will poll the Twitter API on this schedule",
23
- type: "$.interface.timer",
24
- default: {
25
- intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
26
- },
27
- },
28
- },
29
- methods: {
30
- _compareByIdAsc({ id_str: a }, { id_str: b }) {
31
- const A = BigInt(a);
32
- const B = BigInt(b);
33
- if (A < B) return -1;
34
- if (A > B) return 1;
35
- return 0;
36
- },
37
- sortTweets(tweets) {
38
- return tweets
39
- .sort(this._compareByIdAsc);
40
- },
41
- /**
42
- * This function returns the Twitter screen name of the subject account
43
- *
44
- * @returns a string containing the relevant Twitter screen name
45
- */
46
- getScreenName() {
47
- throw new Error("getScreenName is not implemented");
48
- },
49
- /**
50
- * This function provides the list of options for the `tweetId` user prop.
51
- * It is meant to be called by Pipedream during the setup of the user prop
52
- * and not during normal operations of the event source.
53
- *
54
- * @param {object} context the context object for the pagination of the
55
- * prop options
56
- * @param {object} context.prevContext the context object of a previous
57
- * call to this method
58
- * @returns an object containing the list of Tweet ID options for the
59
- * `tweetId` user prop and the context for pagination
60
- */
61
- async tweetIdOptions(context) {
62
- const { prevContext = {} } = context;
63
- const {
64
- screenName = await this.getScreenName(),
65
- sinceId = "1",
66
- } = prevContext;
67
-
68
- const userTimelineOpts = {
69
- screenName,
70
- sinceId,
71
- count: 10,
72
- trim_user: true,
73
- exclude_replies: false,
74
- include_rts: false,
75
- };
76
- const tweets = await this.twitter.getUserTimeline(userTimelineOpts);
77
- if (tweets.length === 0) {
78
- // There are no more tweets to go through
79
- return {
80
- options: null,
81
- context: prevContext,
82
- };
83
- }
84
-
85
- const sortedTweets = this.sortTweets(tweets);
86
- const { id_str: lastId } = sortedTweets[sortedTweets.length - 1];
87
- const options = sortedTweets.map(({
88
- full_text: fullText,
89
- id_str: idStr,
90
- }) => ({
91
- label: fullText,
92
- value: idStr,
93
- }));
94
-
95
- return {
96
- options,
97
- context: {
98
- screenName,
99
- sinceId: lastId,
100
- },
101
- };
102
- },
103
- getSinceId() {
104
- return this.db.get("sinceId") || "1";
105
- },
106
- setSinceId(sinceId = "1") {
107
- this.db.set("sinceId", sinceId);
108
- },
109
- generateMeta(tweet) {
110
- const {
111
- created_at: createdAt,
112
- full_text: fullText,
113
- id_str: id,
114
- text,
115
- } = tweet;
116
- const summary = fullText || text;
117
- const ts = this.twitter.parseDate(createdAt);
118
- return {
119
- id,
120
- summary,
121
- ts,
122
- };
123
- },
124
- /**
125
- * The purpose of this function is to retrieve the relevant Tweets for the
126
- * event source that implements it. For example, if the event source emits
127
- * an event for each new Tweet of a specific user, the implementation of
128
- * this function will perform the retrieval of such Tweets and return it as
129
- * a list of [Tweet
130
- * objects](https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/object-model/tweet)
131
- *
132
- * @returns a list of Tweet objects for which to emit new events
133
- */
134
- retrieveTweets() {
135
- throw new Error("retrieveTweets is not implemented");
136
- },
137
- },
138
- async run() {
139
- const tweets = await this.retrieveTweets();
140
- if (tweets.length === 0) {
141
- console.log("No new tweets available. Skipping...");
142
- return;
143
- }
144
-
145
- const sortedTweets = this.sortTweets(tweets);
146
- const { id_str: lastId } = sortedTweets[sortedTweets.length - 1];
147
- this.setSinceId(lastId);
148
-
149
- // Emit array of tweet objects
150
- sortedTweets.forEach((tweet) => {
151
- const meta = this.generateMeta(tweet);
152
- this.$emit(tweet, meta);
153
- });
154
- },
155
- };